<!DOCTYPE HTML>
<html lang="zh-CN">


<head>
    <meta charset="utf-8">
    <meta name="keywords" content="Python基础知识, JackHCC">
    <meta name="description" content="Python语法语义的基本知识详解">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <meta name="renderer" content="webkit|ie-stand|ie-comp">
    <meta name="mobile-web-app-capable" content="yes">
    <meta name="format-detection" content="telephone=no">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
    <title>Python基础知识 | JackHCC</title>
    <link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/medias/favicon.png">

    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/libs/awesome/css/all.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/libs/materialize/materialize.min.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/libs/aos/aos.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/libs/animate/animate.min.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/libs/lightGallery/css/lightgallery.min.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/css/matery.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/css/my.css">
    
    <script src="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/libs/jquery/jquery.min.js"></script>
    
<meta name="generator" content="Hexo 4.2.0"><link rel="alternate" href="/atom.xml" title="JackHCC" type="application/atom+xml">
<link rel="stylesheet" href="/css/prism-hopscotch.css" type="text/css">
<link rel="stylesheet" href="/css/prism-line-numbers.css" type="text/css"></head>


<body>
    <header class="navbar-fixed">
    <nav id="headNav" class="bg-color nav-transparent">
        <div id="navContainer" class="nav-wrapper head-container">
            <div class="brand-logo">
                <a href="/" class="waves-effect waves-light">
                    
                    <img src="/images/loading.gif" data-original="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/medias/me.jpg" class="logo-img" alt="LOGO">
                    
                    <span class="logo-span">JackHCC</span>
                </a>
            </div>
            

<a href="#" data-target="mobile-nav" class="sidenav-trigger button-collapse"><i class="fas fa-bars"></i></a>
<ul class="right nav-menu">
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/" class="waves-effect waves-light">
      
      <i class="fas fa-home" style="zoom: 0.6;"></i>
      
      <span>首页</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/tags" class="waves-effect waves-light">
      
      <i class="fas fa-tags" style="zoom: 0.6;"></i>
      
      <span>标签</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/categories" class="waves-effect waves-light">
      
      <i class="fas fa-bookmark" style="zoom: 0.6;"></i>
      
      <span>分类</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/archives" class="waves-effect waves-light">
      
      <i class="fas fa-archive" style="zoom: 0.6;"></i>
      
      <span>归档</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/about" class="waves-effect waves-light">
      
      <i class="fas fa-user-circle" style="zoom: 0.6;"></i>
      
      <span>关于</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/contact" class="waves-effect waves-light">
      
      <i class="fas fa-comments" style="zoom: 0.6;"></i>
      
      <span>留言板</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/friends" class="waves-effect waves-light">
      
      <i class="fas fa-address-book" style="zoom: 0.6;"></i>
      
      <span>友情链接</span>
    </a>
    
  </li>
  
  <li>
    <a href="#searchModal" class="modal-trigger waves-effect waves-light">
      <i id="searchIcon" class="fas fa-search" title="搜索" style="zoom: 0.85;"></i>
    </a>
  </li>
</ul>

<div id="mobile-nav" class="side-nav sidenav">

    <div class="mobile-head bg-color">
        
        <img src="/images/loading.gif" data-original="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/medias/me.jpg" class="logo-img circle responsive-img">
        
        <div class="logo-name">JackHCC</div>
        <div class="logo-desc">
            
            Make the world betterrrr!!!
            
        </div>
    </div>

    

    <ul class="menu-list mobile-menu-list">
        
        <li class="m-nav-item">
	  
		<a href="/" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-home"></i>
			
			首页
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/tags" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-tags"></i>
			
			标签
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/categories" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-bookmark"></i>
			
			分类
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/archives" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-archive"></i>
			
			归档
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/about" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-user-circle"></i>
			
			关于
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/contact" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-comments"></i>
			
			留言板
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/friends" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-address-book"></i>
			
			友情链接
		</a>
          
        </li>
        
        
        <li><div class="divider"></div></li>
        <li>
            <a href="https://github.com/JackHCC/JackHCC.github.io" class="waves-effect waves-light" target="_blank">
                <i class="fab fa-github-square fa-fw"></i>Fork Me
            </a>
        </li>
        
    </ul>
</div>

        </div>

        
            <style>
    .nav-transparent .github-corner {
        display: none !important;
    }

    .github-corner {
        position: absolute;
        z-index: 10;
        top: 0;
        right: 0;
        border: 0;
        transform: scale(1.1);
    }

    .github-corner svg {
        color: #0f9d58;
        fill: #fff;
        height: 64px;
        width: 64px;
    }

    .github-corner:hover .octo-arm {
        animation: a 0.56s ease-in-out;
    }

    .github-corner .octo-arm {
        animation: none;
    }

    @keyframes a {
        0%,
        to {
            transform: rotate(0);
        }
        20%,
        60% {
            transform: rotate(-25deg);
        }
        40%,
        80% {
            transform: rotate(10deg);
        }
    }
</style>

<a href="https://github.com/JackHCC/JackHCC.github.io" class="github-corner tooltipped hide-on-med-and-down" target="_blank"
   data-tooltip="Fork Me" data-position="left" data-delay="50">
    <svg viewBox="0 0 250 250" aria-hidden="true">
        <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
        <path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2"
              fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path>
        <path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z"
              fill="currentColor" class="octo-body"></path>
    </svg>
</a>
        
    </nav>

</header>

    



<div class="bg-cover pd-header post-cover" style="background-image: url('https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/medias/featureimages/13.jpg')">
    <div class="container" style="right: 0px;left: 0px;">
        <div class="row">
            <div class="col s12 m12 l12">
                <div class="brand">
                    <h1 class="description center-align post-title">Python基础知识</h1>
                </div>
            </div>
        </div>
    </div>
</div>




<main class="container content">

    
    <!-- 文章内容详情 -->
<div id="artDetail">
    <div class="card">
        <div class="card-content article-info">
            <div class="row tag-cate">
                <div class="col s7">
                    
                    <div class="article-tag">
                        
                            <a href="/tags/Python/">
                                <span class="chip bg-color">Python</span>
                            </a>
                        
                    </div>
                    
                </div>
                <div class="col s5 right-align">
                    
                    <div class="post-cate">
                        <i class="fas fa-bookmark fa-fw icon-category"></i>
                        
                            <a href="/categories/Python/" class="post-category">
                                Python
                            </a>
                        
                    </div>
                    
                </div>
            </div>

            <div class="post-info">
                
                <div class="post-date info-break-policy">
                    <i class="far fa-calendar-minus fa-fw"></i>发布日期:&nbsp;&nbsp;
                    2020-02-28
                </div>
                

                
                <div class="post-date info-break-policy">
                    <i class="far fa-calendar-check fa-fw"></i>更新日期:&nbsp;&nbsp;
                    2020-02-28
                </div>
                

                
                <div class="info-break-policy">
                    <i class="far fa-file-word fa-fw"></i>文章字数:&nbsp;&nbsp;
                    15.5k
                </div>
                

                
                <div class="info-break-policy">
                    <i class="far fa-clock fa-fw"></i>阅读时长:&nbsp;&nbsp;
                    65 分
                </div>
                

                
                    <div id="busuanzi_container_page_pv" class="info-break-policy">
                        <i class="far fa-eye fa-fw"></i>阅读次数:&nbsp;&nbsp;
                        <span id="busuanzi_value_page_pv"></span>
                    </div>
				
            </div>

        </div>
        <hr class="clearfix">
        <div class="card-content article-card-content">
            <div id="articleContent">
                <h1 id="课程笔记"><a href="#课程笔记" class="headerlink" title="$课程笔记"></a>$课程笔记</h1><p><img src="/images/loading.gif" data-original="http://upload-images.jianshu.io/upload_images/14093662-c7908d67f53948e5.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image"></p>
<p><a href="https://www.w3cschool.cn/python/dict" target="_blank" rel="noopener">python相关函数查询</a></p>
<p><a href="https://docs.python.org/zh-cn/3/tutorial/index.html" target="_blank" rel="noopener">官方API文档</a></p>
<p><a href="https://www.runoob.com/python/python-tutorial.html" target="_blank" rel="noopener">菜鸟教程python</a></p>
<p><a href="https://www.w3cschool.cn/python/" target="_blank" rel="noopener">w3school教程python</a></p>
<h3 id="一-基本元素"><a href="#一-基本元素" class="headerlink" title="一.基本元素"></a>一.基本元素</h3><h5 id="变量"><a href="#变量" class="headerlink" title="变量"></a>变量</h5><ul>
<li>变量赋值：<pre><code>a="hello world"</code></pre></li>
<li>变量命名：<br>• 字母：a-z, A-Z, 其他语言的字母符号<br>• 数字：0-9 (不可以出现在首字符)<br>• 下划线：_ （可以单用）</li>
<li>注意事项<br>• 在赋值时，变量即被创建，变量的值和类<br>型在赋值的时候被确定。<br>• 不需要声明（declaration）<br>• 变量名大小写敏感：A, a是不同的变量<br>• 变量可以被重新赋值<h5 id="变量类型"><a href="#变量类型" class="headerlink" title="变量类型"></a>变量类型</h5></li>
<li>数值类型<br>• 整数 Integers: 12 0 -12987 0123 0X1A2 10294L<br>   大致相当于C语言的 ‘int’ 或 ‘long’<br>   范围可以非常大（大致无限）<br>   八进制数以“0” 开始 (0981 是非法的!)<br>   十六进制以0X开始<br>• 浮点数Floating point: 12.03 1E1 -1.54E-21<br>   相当于C语言的double<br>• 复数Complex numbers: 1+3J<pre><code>语言原生支持</code></pre></li>
</ul>
<p><strong>运算注意事项：</strong><br>• 操作符和C语言类似，例如 +, -, /, <em>, %<br>• 幂操作：**</em><br>• 优先级和括号的作用相似</p>
<ul>
<li>逻辑类型<br>• 预定义值：True False<br>• 数值 0 认为是假，其他值认为是真<br>• 操作符：not, and, or</li>
</ul>
<p><strong>运算注意事项：</strong><br>• 比较运算获得逻辑值，运算符: &lt;, &lt;=, &gt;, &gt;=,<br>==, !=</p>
<ul>
<li><p>字符串类型<br>• 使用函数str, int, float等类型名进行转换</p>
<pre><code>b=int(a)
c=flaot(a)
d=str(a)</code></pre><p>• 字符串的拼接和整数乘法</p>
<pre><code>a="hello"+"world"
b="hello"*2</code></pre><h5 id="语句"><a href="#语句" class="headerlink" title="语句"></a>语句</h5></li>
<li><p>代码缩进<br>• Python语 语 言 的 行 前 空 白 是 有 语 法 意 义 的<br>• 在源文件中，应该统一采取一种缩进格式<br>缩进进4个空格 （ 推 荐 标 准 ）<br>缩进2个空格<br>缩进1制表符（tab）<br>上述缩进不可以混用<br>• 连续处于相同缩进层次的语句构成一个语句块（Block）</p>
</li>
<li><p>条件语句</p>
<pre><code>if 条件：
elif 条件：
else:</code></pre></li>
<li><p>循环语句(for)<br>• 循环语句for<br>• range(n)表明从0开始，到n-1（含）。</p>
<pre><code>s = 0
for i in range(10): # 0,1,...9
  s += i
print(s)</code></pre></li>
<li><p>循环语句(while)</p>
<pre><code>s = 0
i = 0
while s&lt;10:
  s += i
  i += 1
print(s)</code></pre></li>
<li><p>导入语句<br>三种写法：</p>
<pre><code>from math import *
# use pi, cos, sin, ...
from math import cos, sin
# only use cos, sin
import math
# use math.cos, math.sin, ...</code></pre></li>
<li><p>定义函数<br>• 用def定义函数，可以有参数和返回值</p>
<pre><code>def double(x):
  return x * 2</code></pre><h5 id="turtle库详解"><a href="#turtle库详解" class="headerlink" title="turtle库详解"></a>turtle库详解</h5><p><a href="https://www.jianshu.com/p/29f5c970fa80" target="_blank" rel="noopener">python：turtle库详解</a></p>
<h3 id="python类型"><a href="#python类型" class="headerlink" title="python类型"></a>python类型</h3><h5 id="类型"><a href="#类型" class="headerlink" title="类型"></a>类型</h5><p>• 标量类型<br>—— 逻辑类型(bool)<br>—— 整数(int)、浮点数(float)、复数(complex)<br>—— 空 类型 型(None)<br>• 集合类型<br>—— 字符串(str)<br>—— 列表(list)<br>—— 字典(dict)<br>—— 元组(tuple)<br>—— 集合(set)<br>• 自定义类型<br>—— 类 class</p>
<h5 id="数值类型"><a href="#数值类型" class="headerlink" title="数值类型"></a>数值类型</h5><p>• 除法有两种：/, // 后者是整除<br>—— 7/3 = 2.3333333333333335<br>—— 7//3 = 2<br>—— 7.0 // 3.0 = 2.0<br>• 幂运算允许实数<br>—— 7 ** 2 = 49<br>—— 7 ** 0.5 = 2.6457513110645907<br>• 不同类型的数值运算就高不就低<br>—— int —— float —— complex</p>
<h5 id="三元操作符"><a href="#三元操作符" class="headerlink" title="三元操作符"></a>三元操作符</h5><p>• 表达式</p>
<pre><code>x if c else y </code></pre><p>相当于</p>
<pre><code>c? x : y</code></pre><h5 id="字符串"><a href="#字符串" class="headerlink" title="字符串"></a>字符串</h5><p>• 字符串的进阶操作</p>
<pre><code>'p' in s </code></pre><p>• 下标以0为开始</p>
<pre><code>s[0] # index: offset 0
s[2:6] # slice: part of string
s[:6] 
s[6:]</code></pre><p>• 逆序的下标</p>
<pre><code>s[-1]
s[-3:-1]
s[1:-1]
s[-3:]</code></pre><p>• 步长：begin:end:step</p>
<pre><code>s[::2]
s[1::3]
s[5:1::-1]
"live"[::-1]</code></pre><h5 id="不可修改类型-Immutable"><a href="#不可修改类型-Immutable" class="headerlink" title="不可修改类型 Immutable"></a>不可修改类型 Immutable</h5><p>• 数值类型、字符串类型是不可修改类型<br>—— 后续讲解的元组（tuple）类型也是不可修改类型<br>• 它们的值是常数，不可以修改<br>—— 我们并不能把“1”修改为“2”，把“abc”改为“def”；<br>—— 作为值，它的含义是确定的、不变的。<br>• 赋值语句（Assignment）是给这些常数的值赋予不同的名称</p>
<h5 id="字符串方法"><a href="#字符串方法" class="headerlink" title="字符串方法"></a>字符串方法</h5><pre><code>s = 'I love Python'
s.count('on') # 查找子串出现次数
s.find('ove') # 查找子串首见位置
s.replace('Python', 'C++') # 替换

three = '3'
three.isdigit() # 是否为数字字符?</code></pre><h5 id="列表"><a href="#列表" class="headerlink" title="列表"></a>列表</h5></li>
<li><p>相关事项<br>• 表（或称为列表，广义表）是python最重要<br>和常用的容器类<br>• 由一系列有序排列的对象构成（Ordered<br>collection of objects）~ C语言的数组<br>• 异构（Heterogenous），一个列表可以包含<br>多种类型的对象。</p>
<pre><code>r = [1, 2.0, 3, 5] # list的字面构造
r[1] # 正数下标自首部计数，首部为0
r[-1] # 负数下标自尾部计数，尾部为-1
r[1:3] # 前闭后开区间
w = r + [10, 19] # 连接
t = [0.0] * 10 # 重复
len(r)</code></pre></li>
<li><p>列表操作</p>
<pre><code>r = [[9, 8], 2.0, 3, 'word']
r[0:3] = [1, 2, 5, 6] # 修改片段

r[1:3] = [] # 删除元素

r[1:1] = [ 'new' ] # 赋值语句左右侧都是片段；等价于插入[1, 'new', 6, 'word']
r[len(r):] = [ 'last' ] # 在尾部插入[1, 'new', 6, 'word', 'last']</code></pre></li>
<li><p>列表的方法</p>
<pre><code>r.insert(0, 'f') # 在0位置增加新元素'f'
del r[0]
r.append(9) # 尾部增加元素
r.sort() # in-place 排序
r.reverse() # 逆序</code></pre></li>
<li><p>判断两个变量是否指向同一对象<br>• 利用id函数，返回对象的唯一标志<br>• id(x) == id(y) 表明x和y实际上是同一对象<br>• x is y</p>
</li>
<li><p>列表推导</p>
<pre><code>[i for i in range(9)]
[i*2 for i in range(9)]
[i for i in range(100) if '4' not in str(i)]</code></pre><p>• 补充<br>—— Python 一行语句过长，可以用 \ 续行<br>—— 若在括号（花方圆均可）内可以自由换行</p>
<h5 id="字典"><a href="#字典" class="headerlink" title="字典"></a>字典</h5></li>
<li><p>基本事项<br>• 字典是一种数据组织方式，它根据 key获得对应的value<br>• key称为键，key是无序的，或者说不关注其顺序。<br>• value称为值，可以是任意的对象。<br>• 字典也称为映射(mapping)、哈希(hash)表、查找表(lookup table)等。</p>
</li>
<li><p>字典操作</p>
<pre><code>g = {'Tom': 'boy', 'Mary': 'girl'}
g['Tom'] # 以key为索引
g.has_key('Mary')
g['Jack'] = 'boy' # 增加键值对
del g['Tom'] # 删除键，删除键到值的绑定

h = {'Tom': 12, 'Mary': 'good'}
'Per' in h # 在键的集合中检测
h.get('Per', 'unknown') # 如果查找失败则返回缺省值
h.keys() # 由键组成的列表，顺序不确定
h.values() # 由值组成的列表，顺序不确定
h.items() # 顺序同上
len(h) # 键的数量</code></pre><h5 id="元组"><a href="#元组" class="headerlink" title="元组"></a>元组</h5></li>
<li><p>注意事项<br>• 与list相同，但不可改变（immutable）<br>• 一旦创建，不可修改。（Once created, can’t be changed.）</p>
<pre><code>t = (1, 3, 2)
t[1] # 3
(a, b, c) = t # 元组赋值
a, b, c # (1, 3, 2)</code></pre><h5 id="集合"><a href="#集合" class="headerlink" title="集合"></a>集合</h5></li>
<li><p>注意事项<br>• 数学中的集合，无序，不重复（set）<br>• 去重的时候很有用</p>
<pre><code>s = set()
s = {1, 2, 3}
s.add(4) # {1,2,3,4}
s.add(1) # {1,2,3,4}
t = {1,2}
# &amp;交集，|并集 - 差集
s - t # {3,4}</code></pre><h5 id="容器间转换"><a href="#容器间转换" class="headerlink" title="容器间转换"></a>容器间转换</h5><p>• list, set, dict 作为类型名可以实现转换<br>—— list(“abc”)    = [“a”, “b”, “c”]<br>—— set([1,2,2])     = {1,2}</p>
<h3 id="Python语句"><a href="#Python语句" class="headerlink" title="Python语句"></a>Python语句</h3><h5 id="pass语句"><a href="#pass语句" class="headerlink" title="pass语句"></a>pass语句</h5><p>• pass是一个（占位）空语句，不做任何事情<br>• 动因<br>—— python利用缩进表达语句块，如果语句块是空的，不写会有错；<br>—— 这种情况下，可以写上pass</p>
<h5 id="for循环语句"><a href="#for循环语句" class="headerlink" title="for循环语句"></a>for循环语句</h5><p>• for可以遍历任意的容器<br>—— 对词典遍历的是keys()<br>• range(n)是一个内置函数，返回0~n-1的列表<br>• range(start, stop, step)</p>
<h5 id="break语句"><a href="#break语句" class="headerlink" title="break语句"></a>break语句</h5><p>• 跳出最内层的循环<br>• python没有直接跳出外层循环的语法手段<br>—— 通常会借助额外的flag变量<br>—— 异常处理</p>
<h5 id="continue语句"><a href="#continue语句" class="headerlink" title="continue语句"></a>continue语句</h5><p>• 它结束当前迭代，并跳到下一次迭代开头。即跳过循环体中余下的语句，但不结束循环。<br>• 可以用等价的if语句描述</p>
<h5 id="for-while-else语句"><a href="#for-while-else语句" class="headerlink" title="for/while-else语句"></a>for/while-else语句</h5><p>• 只要不是break跳出循环，就执行else语句<br>• 相比C语言减少一个flag变量</p>
<pre><code>r = [1, 3, 10, 98, -2, 48]
for i in r:
  if i &lt; 0:
      print('input contains negative value!')
      break
else:
  print('input is OK')</code></pre><h5 id="exec和eval"><a href="#exec和eval" class="headerlink" title="exec和eval"></a>exec和eval</h5><p>• 动态地编写Python代码，并将其作为语句进<br>行执行或作为表达式进行计算<br>• 函数exec将字符串作为代码执行<br>• eval计算用字符串表示的Python表达式的值，<br>并返回结果。<br>• 如下代码来创建一个Python计算器</p>
<h5 id="assert断言语句"><a href="#assert断言语句" class="headerlink" title="assert断言语句"></a>assert断言语句</h5><p>• 要求某些条件得到满足，否则将引发异常<br>• 确保程序的参数合理<br>• 对于不合理的情况，明确引发异常</p>
<h5 id="异常处理"><a href="#异常处理" class="headerlink" title="异常处理"></a>异常处理</h5></li>
<li><p>完整的异常处理</p>
<pre><code>try:
  1 / 0
except NameError:
  print("Unknown variable")         出现异常时执行。。。
else:
  print("That went well!")             没有出现异常时执行
finally:
  print("Cleaning up.")             任何情况下都会执行</code></pre><h5 id="函数"><a href="#函数" class="headerlink" title="函数"></a>函数</h5><p>• 函数名：规则与变量名相同<br>• 参数列表：调用函数时传递给它的值<br>—— 可以由零个，一个或者多个参数组成<br>—— 当有多个参数时，各个参数用逗号分隔<br>• 函数体：函数被调用时执行的代码<br>—— 由一个或多个语句组成<br>—— 在执行到末尾或return语句时退出函数<br>—— 返回结果<br>• 函数调用的形式<br>—— 函数名( 参数列表 )<br>• 形式参数（名）：定义函数时，函数名后面圆括号中的变量。形参只在函数内部有效。<br>• 实际参数（值）：调用函数时，函数名后面圆括号中的变量。</p>
<h5 id="参数能否修改：总结"><a href="#参数能否修改：总结" class="headerlink" title="参数能否修改：总结"></a>参数能否修改：总结</h5><p>• 凡是Immutable类型的参数，传入的对象值不可能修改<br>• 对于Mutable类型的参数：<br>—— 若对形参进行赋值，并不能改变传入对象的值<br>—— 若对形参进行in-place的修改，则该修改也反应在传入的对象上</p>
<h5 id="关键字参数的缺省值"><a href="#关键字参数的缺省值" class="headerlink" title="关键字参数的缺省值"></a>关键字参数的缺省值</h5><p>• 可以设定一些参数的缺省值（默认值）<br>• 如果调用者没有提供，则使用缺失值</p>
<pre><code>def hello(name, greeting="Hello"):</code></pre><p>• 允许用户提供任意数量的参数</p>
<pre><code>def sum_of_all(*values):</code></pre><h5 id="作用域"><a href="#作用域" class="headerlink" title="作用域"></a>作用域</h5></li>
<li><p>注意事项<br>• 如果没有局部变量和全局变量同名，可以直接读取全局变量。<br>• 如果有一个局部变量与待访问的全局变量同名，则无法直接访问全局变量，因为它被局部变量遮住了。<br>• 可以使用关键字 global（nonlocal）修饰变量名，表明和全局（外层）变量关联。<br>• Python的函数可以作为返回值</p>
<h5 id="匿名函数"><a href="#匿名函数" class="headerlink" title="匿名函数"></a>匿名函数</h5><p>• lambda可以用来定义函数</p>
<pre><code>pow2_a = lambda x: x*x
def pow2_b(x):
    return x*x</code></pre><p>两者功能相同</p>
<h5 id="模块"><a href="#模块" class="headerlink" title="模块"></a>模块</h5><p>• 对于稍微大型的程序，代码量较大，不宜<br>放在一个文件中<br>• 模块可以将代码分散在不同的文件</p>
<h5 id="主模块"><a href="#主模块" class="headerlink" title="主模块"></a>主模块</h5><pre><code>if __name__ == "__main__":
    do_something()</code></pre><h3 id="文本处理"><a href="#文本处理" class="headerlink" title="文本处理"></a>文本处理</h3><h5 id="字符的分类"><a href="#字符的分类" class="headerlink" title="字符的分类"></a>字符的分类</h5><p>• 数字 digits 01234567890<br>• 字母 letter<br>大写ABCDEFGHIJKLMNOPQRSTUVWXYZ<br>小写 abcdefghijklmnopqrstuvwxyz<br>• 空白字符：空格，\t\n\r\v<br>• 对应Unicode，上述概念有一定拓展。</p>
<h5 id="字符串对象方法"><a href="#字符串对象方法" class="headerlink" title="字符串对象方法"></a>字符串对象方法</h5></li>
<li><p><strong>capitalize()</strong> 字符串首字母大写</p>
</li>
<li><p><strong>lower()</strong> 转为小写</p>
</li>
<li><p><strong>upper()</strong> 转为大写</p>
</li>
<li><p><strong>find(s)/rfind(s)</strong>  正向/逆向查找子串s的出现位置</p>
</li>
<li><p><strong>count(s)</strong>  查找s出现的次数</p>
</li>
<li><p><strong>strip()</strong>  移除开始和结束的空白</p>
</li>
<li><p><strong>lstrip()/rstrip()</strong>移除开始/结束的空白</p>
</li>
<li><p><strong>replace(s, r)</strong> 将子串s替换为r（缺省为全替换，可以仅替换指定次数）</p>
</li>
<li><p><strong>isalpha()/isdigit()</strong> 是否是字母、数字等……</p>
</li>
<li><p><strong>isupper()/Islower()</strong> 是否大写小写等….</p>
</li>
<li><p><strong>startswith(s)/endswith(s)</strong> 是否以s作为字符串的开始或结尾</p>
</li>
<li><p><strong>s.split(sep)</strong> 将字符串sep作为分隔符，对字符串s进行分解，返回列表</p>
</li>
<li><p><strong>sep.join(parts)</strong>  将各部分用分隔符sep连接在一起</p>
</li>
</ul>
<h5 id="格式化"><a href="#格式化" class="headerlink" title="格式化"></a>格式化</h5><p>• 字符串的格式化有三种方法<br>• %, format, f-string</p>
<ul>
<li>% 操作符</li>
</ul>
<p><strong>用法:</strong> str % parameter_tuple</p>
<pre><code>"the number is %d" % 30</code></pre><ul>
<li>%-format</li>
</ul>
<p><strong>%c</strong> character<br><strong>%s</strong> string conversion via str() prior to formatting<br><strong>%i</strong>  signed decimal integer<br><strong>%d</strong> signed decimal integer<br><strong>%u</strong> unsigned decimal integer<br><strong>%o</strong> octal integer<br><strong>%x</strong> hexadecimal integer (lowercase letters)<br><strong>%X</strong> hexadecimal integer (UPPERcase letters)<br><strong>%e</strong> exponential notation (with lowercase ‘e’)<br><strong>%E</strong> exponential notation (with UPPERcase ‘E’)<br><strong>%f</strong> floating point real number<br><strong>%g</strong> the shorter of %f and %e<br><strong>%G</strong> the shorter of %f and %E<br><strong>*</strong> argument specifies width or precision<br><strong>-</strong>  left justification<br><strong>+</strong> display the sign<br><strong><sp></sp></strong> leave a blank space before a positive number<br><strong>#</strong> add the octal leading zero ( ‘0’ ) or hexadecimal leading ‘0x’or ‘0X’, depending on whether ‘x’ or ‘X’ were used.<br><strong>0</strong> pad from left with zeros (instead of spaces)<br><strong>%</strong> ‘%%’ leaves you with a single literal ‘%’<br><strong>(var)</strong> mapping variable (dictionary arguments)<br><strong>m.n.</strong> m is the minimum total width and n is the number of digitsto display after the decimal point (if appl.)</p>
<pre><code>name = "John"
age = 23
print("%s is %d years old." % (name, age))</code></pre><ul>
<li>str.format方法<br>• 原先的用法：’%s %s’ % (‘one’, ‘two’)<br>• 目前的用法：’{} {}’.format(‘one’, ‘two’)<pre><code>"{0} {1}, you may have won ${2}" .format("Mr.", "Smith",10000)
'int, {0:5}, in a field of width 5'.format(7)
' {0:10.5f}, fixed at 5 decimal places.'.format(3.1415926)</code></pre></li>
<li>f-string<pre><code>name = "Eric"
age = 24
f"Hello, {name}. You are {age}."</code></pre>f-string是python3版本的新语法，是一种表达式。</li>
<li>split-join<br>• split用于将长字符串进行分解<br>• join用于合并短字符串<br>• 常见的分隔符号有：\t , ; . - /<pre><code>"www.ustb.edu.cn".split(".")
[ int(i) for i in "166.111.4.80".split(".") ]
".".join([ f"{i}" for i in [166, 111, 4, 80] ])</code></pre><h5 id="正则表达式"><a href="#正则表达式" class="headerlink" title="正则表达式"></a>正则表达式</h5></li>
<li>通配符：匹配任意字符</li>
<li>字符组（类）<br>• 字符类 [] 用于匹配一组字符<br>• 可以用 [^] 表达不匹配组里面的任意字符<br>• Ranges 可以表示一个范围的字符<br>—— [1-9] 即 [123456789]<br>—— [abcde] 即 [a-e]<br>—— [abcde123456789] 即 [a-e1-9]</li>
<li>预定义的字符组</li>
</ul>
<p><strong>\d</strong>  数字 [0-9]<br><strong>\D</strong> 非数字 [^0-9]<br><strong>\s</strong> 空白字符 [ \f\n\r\t\v]<br><strong>\S</strong> 非空白字符 [^ \f\n\r\t\v]<br><strong>\w</strong> 字母数字下划线 [A-Za-z0-9_]<br><strong>\W</strong> 非字母数字下划线 [^A-Za-z0-9_]</p>
<ul>
<li>锚 Anchors<br>• ^ 即行首 beginning of the line，在多行模式下匹配每行的开始位置<br>• $ 即行尾 means end of the line，在多行模式下匹配每行的结束位置<br>• \A 仅行首<br>• \Z 仅行尾<br>• \b 匹配单词的边界<br>—— 从字母数字到非字母数字的过渡边界，\w\W 或 \W\w</li>
<li>重复指示Repetions<br>• 三种 * + ?<br>• * 指示其前置内容0<del>+inf次出现，也就是<br>任意多次<br>• + 1</del>+inf<br>• ? 0~1</li>
<li>重复数量的范围指示<br>• 可以用 {n,m} 指示范围<br>—— {n,m} 表示n~m次<br>—— {n} 表示恰好n次 exactly n occurrences<br>—— {n,} 表示至少n次 at least n occurrences<br>• 示例:<br>—— .{0,} 等价于 .*<br>—— a{2,} 等价于 aaa*</li>
<li>子表达式<br>• 重复指示仅修饰其前面的一个符号，如果<br>想表示多个符号，需要对正则表达式进行<br>分组，用 （）进行划分，称为子表达式<br>• 子表达式作为一个整体被修饰<br>—— a* 匹配a的0次货多次出现<br>—— abc* 匹配 ab, abc, abcc, abccc, …<br>—— (abc)* 匹配 abc, abcabc, abcabcabc, …<br>—— (abc){2,3} 匹配 abcabc or abcabcabc</li>
<li>或<br>• 符号 | 表示匹配该符号前面的或后面的子表达式<br>—— (T|Fl)an 匹配 Tan or Flan<br>—— ^(From|Subject): 匹配邮件头部<br>• 优先级最低，可以用 （） 改变<br>•  示例：<br>—— At(ten|nine)tion 匹配Attention or Atninetion<br>—— 不能匹配Atten or ninetion 除非未加括号即Atten|ninetion</li>
<li>转义<br>• 很多字符（如“.”）在正则表达式中有特殊含义，如果只代表它原本的字面意义就需要转义，例如“.”仅匹配句点本身。<br>—— 目标仅匹配单个句点： .<br>—— 在正则表达式层面需要看到： .<br>—— 在字符串书写时需要写： “\.”<br>• 匹配反斜线<br>—— 目标仅匹配单个反斜线： <br>—— 在正则表达式层面需要看到： \<br>—— 在字符串书写时需要写： “\\“<br>• 匹配数字\d<br>—— 在正则表达式层面需要看到： \d<br>—— 在字符串书写时需要写： “\d”</li>
</ul>
<p>• 匹配国内电话号码：\d{3}‐\d{8}|\d{4}‐\d{7}<br>—— 如 0511-4405222 或 021-87888822<br>• 腾讯QQ号：[1‐9][0‐9]{4,}<br>—— 腾讯QQ号从10000开始<br>• 中国邮政编码：[1‐9]\d{5}(?!\d)<br>—— 中国邮政编码为6位数字<br>• 匹配身份证：\d{15}|\d{18}<br>—— 中国的身份证为15位或18位<br>• 匹配ip地址：\d+.\d+.\d+.\d+<br>—— 提取ip地址时有用</p>
<ul>
<li><p>子表达式的引用<br>• \n  此处n是一个数字，表示第n个子表达式的值。子表达式的序号按左括号计数。<br>• 例如：<br>—— (.+) \1 匹配 55 55，或者the the<br>• 可以给子表达式予以命名<br>• (?P<name>…)<br>• (?P=name)</name></p>
<h5 id="Python的正则表达式模块"><a href="#Python的正则表达式模块" class="headerlink" title="Python的正则表达式模块"></a>Python的正则表达式模块</h5><p>• 模块导入 <strong>import re</strong><br>• 匹配：re.match() 查找字符串的开始部分是否匹配，不向后查找（类似字符串startswith）<br>• 查找：re.search() 查找是否存在匹配（类似字符串find）<br>• 替换：re.sub() 替换正则表达式（类似字符串replace）</p>
</li>
<li><p>match的用例</p>
<pre><code>s = "2019‐03‐20 is a rainy day"
pat = "\\d‐\\d‐\\d"
m = re.match(pat, s)

m.start()
m.end()
m.group()  #返回匹配对象(Match)，有start, end, group方法</code></pre></li>
<li><p>search的用例</p>
<pre><code>s = "It is reported that 2019‐03‐20 is a rainyday."
pat = "\\d‐\\d‐\\d"
m = re.search(pat, s)
m.start()
m.end()
m.group() </code></pre></li>
<li><p>多次查找findall/finditer</p>
<pre><code>s = """You smiled and talked to me of nothing and I felt that for this I had been waiting long."
re.findall("\\b(\\w+ed)\\b", s)
re.finditer(...) # 类似，但返回一个个Match对象</code></pre></li>
<li><p>替换sub<br>• 04/30/2018 转换为 2018-04-30<br>• 利用re.sub</p>
<pre><code>import re
print re.sub("([0‐9]{2})/([0‐9]{2})/([0‐9]{4})",
"\\3‐\\1‐\\2",
"This is a test 01/30/2019.")</code></pre><h5 id="文件"><a href="#文件" class="headerlink" title="文件"></a>文件</h5></li>
<li><p>基础概念<br>• 文件包括两种类型：文本文件和二进制文件<br>• 二进制文件：直接由比特0和比特1组成，没有统一字符编码，文件内部数据的组织格式与文件用途有关。<br>• 文本文件：以ASCII码方式存储的文件。<br>• 二进制文件和文本文件区别：仅编码（人为的理解）存在差异。<br>• 文件包括两种类型：文本文件和二进制文件<br>• 二进制文件：直接由比特0和比特1组成，没有统一字符编码，文件内部数据的组织格式与文件用途有关。<br>• 文本文件：以ASCII码方式存储的文件。<br>• 二进制文件和文本文件区别：仅编码（人为的理解）存在差异。</p>
</li>
<li><p>文件操作<br>• 打开文件 open<br>—— 建立磁盘上的文件与程序中的对象相关联<br>—— 通过相关的文件对象获得<br>• 文件操作<br>—— 读取<br>—— 写入<br>—— 定位<br>—— 其它：追加、计算等<br>• 关闭文件 close<br>—— 切断文件与程序的联系<br>—— 写入磁盘，并释放文件缓冲区</p>
</li>
<li><p>文件打开操作<br>• 打开文件<br>—— Python使用open()函数打开文件并返回文件对象：</p>
<pre><code>&lt;变量名&gt;=open(file, mode = 'r')</code></pre><p>—— open函数有两个参数：文件名和打开模式。文件名可以是包含完整路径的名字，或当前路径下的文件名。<br>—— 第二个参数制定文件打开模式。<br>• open()函数提供7种基本的打开模式</p>
</li>
</ul>
<p><strong>‘r’</strong>  以只读方式打开文件（默认）如果文件不存在，返回异常FileNotFoundError。<br><strong>‘w’</strong> 以写入的方式打开文件，文件不存在则创建，会覆盖已<br>存在的文件。<br><strong>‘x’</strong> 打开一个新文件来写数据。文件不存在则创建，如果数<br>据已经存在则返回异常FileExistsError。<br><strong>‘a’</strong> 以写入模式打开，文件不存在则创建，如果文件存在，<br>则在末尾追加写入。<br><strong>‘b’</strong> 以 二进制模式打开文件。<br><strong>‘t’</strong> 以 文本模式打开 （默认）。<br><strong>‘+’</strong> 可读写模式（可添加到其它模式中使用）。<br>• 模式的组合使用<br>—— ‘r’,’w’,’x’,’a’可以和’b’,’t’,’+’组合使用，形成既表达读写又表达文件模式的方式。<br><strong>例如：</strong><br>——‘wb’表示“写二进制数据”<br>——‘x+b’表示读写一个新的二进制文件</p>
<ul>
<li>文件的读写操作<br>• 文件的读写：根据打开方式不同可以对文件进行相应的读写操作，Python提供4个常用的文件内容读取方法。</li>
</ul>
<p><strong><file>.readall()</file></strong> 读入整个文件内容，返回一个字符串或字节流。<br><strong><file>.read(size=‐1)</file></strong> 从文件读取size个字符，当未给定size或给定负值的时候，读取剩余的所有字符，文件指针指向文件末尾。<br><strong><file>.readline(size=‐1)</file></strong> 从文件中读入一行内容，如果给出参数，读入该行前size长度的字符串或字节流。<br><strong><file>.readline(hint=‐1)</file></strong>从文件中读入所有行，以每行为元素形成一个列表，如果给出参数，读入hint行。<br>• Python提供3个与文件内容写入有关的方法。<br><strong><file>.write(str)</file></strong> 将字符串str写入文件。<br><strong><file>.writelines(lines)</file></strong>将一个元素为字符串的列表写入文件。<br><strong><file>.seek(offset,from)</file></strong>改变当前文件操作指针的位置，从from(0代表文件起始位置，1代表当前位置，2代表文件末尾）偏移offset个字节。</p>
<ul>
<li>文件操作示例<br>• 文本文件逐行打印输出<pre><code>fo = open(fname ,"rt")
for line in fo.readlines():
  print(line)
fo.close()</code></pre></li>
<li>文件操作示例<pre><code>f1 = open(f1name, "rt")
f2 = open(f1name, "wt")
f2.write(f1.read().upper())
f1.close()
f2.close()</code></pre></li>
<li>with语句<br>• 容易忘记关闭(close)文件<pre><code>f = open('todos.txt')
for chore in f
  print(chore, end='')
tasks.close()
#使用with语句重写这个代码
with open('todos.txt') as f:
for chore in f:
  print(chore, end='')</code></pre>• with确保即使发生异常，也可以正确的关闭文件</li>
<li>编码的文件<br>• 若打开有编码的文件，需要用codecs模块<br>• import codecs<pre><code>f1 = codecs.open(fname, "r", "utf‐8")
f2 = codecs.open(fname, "w", "gb2312")</code></pre></li>
<li>词频统计<pre><code>f = open("alice.txt", "rt")
all = f.read()
f.close()
count_word = {}
for w in all.split():
  w_lowercase = w.lower()
  count_word[w_lowercase] = \
                                      count_word.get(w_lowercase, 0) + 1
result = [(v, k) for k, v in count_word.items()]
result.sort()
top10 = result[‐10:]
for v,k in top10[::‐1]:
  print(f"Word {k}, occurs {v} times")</code></pre><h5 id="汉字的处理"><a href="#汉字的处理" class="headerlink" title="汉字的处理"></a>汉字的处理</h5></li>
<li>导入库<br>• pip install regex<br>• import regex as re<br>• \p{han} 匹配汉字</li>
<li>汉字分词<br>• jieba是Python中一个重要的第三方中文分词函数库。<br>• 第三方库，需要安装</li>
</ul>
<p><strong>jieba.cut(s)</strong> 精确模式，返回一个可迭代的数据类型<br><strong>jieba.cut(s,cut all=True)</strong> 全模式，输出文本s中所有可能单词<br><strong>jieba.cut_for_search(s)</strong> 搜索引擎模式，适合搜索引擎建立索引的分词结果<br><strong>jieba.lcut(s)</strong> 精确模式，返回一个列表类型，建议使用<br><strong>jieba.lcut(s,cut all=True)</strong> 全模式，返回一个列表类型，建议使用<br><strong>jieba.lcut_for_search(s)</strong> 搜索引擎模式，返回一个列表类型，建议使用<br><strong>jieba.add_word(w)</strong> 向分词词典中增加新词w</p>
<h3 id="OOP编程"><a href="#OOP编程" class="headerlink" title="OOP编程"></a>OOP编程</h3><h5 id="类"><a href="#类" class="headerlink" title="类"></a>类</h5><p>• 类是类型概念的发展。<br>—— 对象是广义的“数据值”。<br>—— 对象所属的数据类型就是“类”。<br>—— 用于描述复杂数据的静态和动态行为。<br>• 类（class）：描述相似对象的共性。包括<br>—— 数据<br>—— 操作：方法（method）<br>• 对象是类的实例（instance）<br>—— 创建对象<br>• 类的封装:数据和操作结合成一个程序单元,对外部隐藏内部实现细节。<br>—— 不允许用户直接操作类中被隐藏的信息。<br>—— 用户也无需了解隐藏的信息就能使用该类。<br>• 类对外公开方法名称和调用格式,即界面。<br>—— 外界向对象发消息。(方法名及参数)<br>—— 对象响应消息,执行相应方法。<br>—— 外界只能按对象允许的方式来处理对象数据。<br>• 封装的好处<br>—— 安全:对象自己的方法处理自己的数据<br>—— 易用:使用者无需了解内部实现细节<br>—— 易维护:实现者修改内部实现不会影响使用者<br>—— 标准化:同类甚至不同类的对象对使用者都呈现同样的操作界面<br>• 方法定义同函数定义</p>
<pre><code>def &lt;methodname&gt;(self, other params):</code></pre><p>—— 方法是依附于类的函数,普通函数则是独立的。<br>—— 方法的第一个参数是专用的，习惯用名字self。<br>—— 大体上等价于C++的this<br>—— 只能通过向对象发消息来调用方法。<br>• 对象是数据和操作的结合。<br>—— 方法对应于操作<br>—— 对象的数据以实例变量形式定义。<br>—— 实例变量：self.varname<br>—— 对象变量和所指向的数据本质上是一个词典<br>—— self.varname  即 self[“varname”]<br>—— 实例变量的赋值主要出现在<strong>init</strong>()方法中。</p>
<ul>
<li>类的定义实例<pre><code>class Circle:
""" Class definition for a circle """
def __init__(self, radius):
  self.radius = radius
def getRadius(self):
  return self.radius
def getArea(self):
" Obtain the area of a circle"
  return math.pi*self.radius**2</code></pre></li>
<li>创建实例<br>• 实例创建<br>&lt; 变量&gt; = &lt; 类名&gt; （&lt; 实参&gt; ）<br>这里&lt;类名&gt;相当于一个函数，称为构造器，用来构造实例。<br>• 成员访问<br>• 方法调用<br>—— 类似函数调用,但需指明实例(对象)<br>—— &lt; 实例&gt;.&lt; 方法名&gt;(&lt; 实参&gt;)<br>—— &lt;实例&gt;就是与形参self对应的实参<br>• 数据成员访问<br>—— &lt; 实例&gt;.&lt; 数据成员名&gt;<h5 id="继承"><a href="#继承" class="headerlink" title="继承"></a>继承</h5>• 在OOP程序设计中，当我们定义一个class的时候，可以从某个现有的class继承，新的class称为子类（Subclass），而被继承的class称为基类、父类或超类（Base class、Super class） 。<br>• 继承是面向对象的重要特征之一，继承是两个类或者多个类之间的父子关系，子类继承了父类的所有实例变量和方法。<br>• 继承实现了代码的重用。重用已经存在的数据和行为，减少代码的重新编写。<br>• Python在类名后用一对圆括号表示继承关系，括号中的类表示父类。<pre><code>class 类名（被继承的类）：</code></pre></li>
<li>实例和类的关系判定<br>• isinstance(s, t)函数判定s是否t类型（及其子类型）<br>—— isinstance(c, Circle)<br>—— isinstance(c, DrawableCircle)<br>• 继承关系：is-a  （注：相当于c++的公有继承）<br>• DrawableCircle is a Circle<br>• 一个实例属于某个子类，则也属于父类，反之则不行。<h5 id="多态"><a href="#多态" class="headerlink" title="多态"></a>多态</h5>• 当对一个对象调用draw()函数时，它会根据自己的对象类型执行不同的draw方法<br>—— FilledDrawableCircle.draw()<br>—— DrawableCircle.draw()<br>• 对于相同的方法，会有不同的实现版本，这就是多态（Polymorphism）<h3 id="科学计算与可视化"><a href="#科学计算与可视化" class="headerlink" title="科学计算与可视化"></a>科学计算与可视化</h3><h5 id="Numpy"><a href="#Numpy" class="headerlink" title="Numpy"></a>Numpy</h5>• NumPy（Numeric Python）是Python语言的一个扩展包。<br>• 由多维数组对象和数组计算函数共同组成的库，支持多维数组、矩阵运算以及大量数值计算功能。</li>
<li>Numpy产生动机<br>• 标准的Python中用列表(list)保存一组值，可以作为数组使用。<br>• Python列表的元素可以是任何对象，因此对象需要额外的信息保存其类型等信息，Python本身是解释型语言。因此，对数值运算来说，效率较低。<br>—— 1000*1000的矩阵乘法，基于python实现三层循环超过10分钟。<br>—— Numpy 大约0.03秒。<br>• 计算效率直接影响了科学计算、机器学习的可用性。<br>• Python的列表不支持数值计算语义<br>• 能否实现矢量、矩阵的加法？乘法？逆？<br>• 因此，需要原生支持数值计算语义的，高效率的Python库<br>• NumPy的诞生弥补了这些不足<br>• NumPy提供了两种基本的对象<br>—— ndarray（ndimensional array object ）<br>—— ufunc（ universal function object）<br>• ndarray(数组)是存储单一数据类型的多维数组。<br>• ufunc 是对数组进行处理的函数。<pre><code>• 安装：pip install numpy
• 导入：import numpy as np</code></pre></li>
<li>Numpy的优势<br>• NumPy 通 常 与 SciPy(Scientific Python)和Matplotlib(绘图库)一起使用，这种组合广泛用于替代Matlab，已成为流行的技术方案。<br>• Python：通用语言<br>• Matlab：专用语言<br>• NumPy是开源的（Open-Source）</li>
<li>Numpy做什么<br>• 矢量、矩阵和高维数组（张量）的数值运<br>算和逻辑运算<br>• 线性代数相关的操作<br>• 随机数生成<br>• 傅立叶变换<br>• 图形操作<br>• 其他功能</li>
<li>量<br>• 矢量 Vectors<br>• 矩阵 Matrices<br>• 图像 Images<br>• 张量 Tensors</li>
<li>Ndarray<br>• ndarray：N维数组类型<br>• 描述相同类型的元素集合<br>• 使用基于零的索引访集合中的项目<br>• ndarray中的每个元素类型（dtype）相同，占用的内存大小也相同。</li>
<li>Ndarray的创建<br>• numpy.array(object, dtype = None, order =None)<br>• object通常是一个容器或迭代器，根据其内容生成一个ndarray对象实例<br>• dtype如果不指定，自动从实际数据中推断<br>• order和内存中数据排列有关</li>
<li>dtype<br>• int8, int16, int32, int64<br>• uint8, uint16, uint32, uint64<br>• float16, float32, float64<br>• complex64, complex128</li>
<li>数组属性<br>• 数组的维度：ndim<br>• 数组的形状：shape<pre><code>import numpy as np
x = np.array([1, 2, 3])
y = np.array([4.0, 5, 6])
print(x.dtype, x.shape, x.ndim)
print(y.dtype, y.shape, y.ndim)
z = x + y
print(z)</code></pre></li>
<li>数组创建<br>• 数组创建的其他方法<br>—— numpy.empty：空，不初始化值，值可能任意<br>—— numpy.zeros：0<br>—— numpy.ones：1<br>—— numpy.arange：start, stop, step 可以为浮点数，但是不推荐用在浮点数场合。<br>—— numpy.linspace：start, stop, number 实现均匀划分（默认含右侧端点），推荐在浮点数场合使用。<pre><code>array = np.array([[0,1,2],[2,3,4]])
# [[0 1 2]
#  [2 3 4]]
array = np.zeros((2,3))
# [[0. 0. 0.]
# [0. 0. 0.]]
array = np.ones((2,3))
# [[1. 1. 1.]
# [1. 1. 1.]]</code></pre>• eye 单位矩阵<br>• 浮点数优先用linspace，避免累计误差<br>• np.random 类似于random<pre><code>array = np.eye(3)
# [[1. 0. 0.]
# [0. 1. 0.]
# [0. 0. 1.]]
array = np.arange(0, 10, 2)
# [0, 2, 4, 6, 8]
array = np.linspace(0, 1, 11)
# [0. , 0.1, 0.2, 0.3,…, 0.7, 0.8, 0.9, 1. ]
array = np.random.randint(0, 10, (3,3))
# [[6 4 3]
# [1 5 6]
# [9 8 5]])</code></pre></li>
<li>索引和切片(slice)<br>• 一维数组的索引和切片大体与list相同<pre><code>a = np.arange(9)
a[0]
# 0
a[3:7]
# array([3, 4, 5, 6])
a[:7:2]
# array([0, 2, 4, 6])
a[::‐1]
#array([8, 7, 6, 5, 4, 3, 2, 1, 0])</code></pre>• 多维数组：每一个维度都可以进行索引或切片，<br>返回一个标量或多维的子数组（view）。<br>• 对此子数组的修改可能会反应在原数据上！<pre><code>b = np.array([[0,1,2],[3,4,5]])
#[[0 1 2]
#  [2 3 4]]
b[0,1]
# 1
b[1,:]
#[3,4,5]
b[:,2]
#[2,5]</code></pre></li>
<li>数组的运算<br>• shape相同的多维数组，支持+ ‐ * / % &lt; &gt; == &gt;= &lt;= 等运算，对应的元素逐个进行运算，返回具有相同shape的多维数组<br>• 单目运算作用在数组上，对每个元素逐个实施，包括负号 ‐ 以及单自变量函数 sin,cos 等<br>• 上述运算是element-wise意义上的<pre><code>arr = np.array([[1., 2., 3.], [4., 5., 6.]])
print(arr)
[[1. 2. 3.]
[4. 5. 6.]]
print(arr * arr)
[[ 1. 4. 9.]
[16. 25. 36.]]
print(arr ‐ arr)
[[0. 0. 0.]
[0. 0. 0.]]</code></pre></li>
<li>数组的运算：广播<br>• shape不相同的数组如何运算？<br>• 一般意义的逐元素的运算不可实现。<br>• 但可以通过广播实现，小的数组被广播为大的数组，从而使得两个数组兼容。<br>• 在下列规则满足时可以广播：<br>—— 维数小的数组，在它的shape前面补“1”<br>—— 在某个维度两个数组大小或者相同或者有一个是“1”<br>—— 如果在某个维度是“1”，则需要任何下标[*]时，用[0]元素代替（相当于复制为很多份）<br>• 等价地说，广播运算在下列情况之一成立时可以执行<br>—— 具有相同的shape<br>—— 具有相同的维度，shape每一维的值或者相同或者有一方为1<br>—— 具有不同的维度，但是维数少的在前面补齐“1”后符合上述条件</li>
<li>逻辑型数组索引<br>• 逻辑型数组可以作为索引<br>—— 如比较运算的结果为一个逻辑型数组<br>• 掩码（Mask），表示仅取索引True的元素，构成一个子数组。<pre><code>x = np.arange(10)
mod5 = x % 1 == 1
x [ mod5 ] # [1, 6]
x [ x &gt; 5 ] ?</code></pre>• 整数型数组（或list）可以作为索引<br>• 逐个取出每个整数对应下标的元素，得到ndarray数组的子集<pre><code>x = np.arange(10)*10
# array([ 0, 10, 20, 30, 40,
50, 60, 70, 80, 90])
x[[1,3]]
# array([ 10, 30])
x[[5,3,7]]
# array([ 50, 30, 70])</code></pre></li>
<li>view和copy<br>• 为了提高效率、节约空间，有些numpy操作返回的是view，对view的修改可以改动原始数组中的数据改动原始数组中的数据。<br>• 具体返回view或copy需要查看函数说明。<br>• 显式的复制可以用copy函数。<br>—— a.copy()<br>—— np.copy(a)</li>
<li>数组的拼接<br>• np.concatenate([a1, a2, …],axis=0, out=None)<br>• 参数说明：<br>—— a1, a2, … : 一系列的ndarray，必需是相同的shape，除非在第axis维可以存在差异。<br>—— axis : int, 缺省为0<br>• 按照第axis维把上述数组拼接在一起<pre><code>A = np.ones((4,1))
array([[1.],
[1.],
[1.],
[1.]]
B = np.zeros((4,2))
array([[0., 0.],
[0., 0.],
[0., 0.],
[0., 0.]])
C = np.concatenate([A, B], axis=1)
array([[1., 0., 0.],
[1., 0., 0.],
[1., 0., 0.],
[1., 0., 0.]])</code></pre></li>
<li>数组的创建<br>• np.zeros_like<br>• np.ones_like<br>• np.empty_like<br>• 参数是另一个数组，按照其形状创建一个0/1/空的数组</li>
<li>reshape<br>• 在保持总元素的数目不变的条件下，数组的形状可以更改<br>• 默认的order是row-major<pre><code>a = np.array([1,2,3,4,5,6])
a = a.reshape(3,2)
"""array([[1, 2],
[3, 4],
[5, 6]])"""
a = a.reshape(2,‐1)</code></pre></li>
<li>平坦化<br>• .ravel()<br>• .flat<pre><code>x = np.array([[1, 2, 3], [4, 5, 6]])
print(np.ravel(x))
[1 2 3 4 5 6]
for i in x.flat: #属性，不需要加()，返回iterator
  print(i)</code></pre></li>
<li>转置<br>• .transpose 交换两个轴 axes<br>• .T 相当于transposes前两个轴<pre><code>x = np.arange(4).reshape((2,2))
"""array([[0, 1],
[2, 3]])"""
np.transpose(x) # x.transpose((1,0)), or x.T
"""array([[0, 2],
[1, 3]])"""</code></pre></li>
<li>数组的IO<br>• 可以存储为NPY/NPZ文件<br>• 可以同时存储多个数组<br>• save存储为非压缩格式<br>• savez存储压缩格式<pre><code>np.savez('data.npz', a=a)
data = np.load('data.npz')
a = data['a'] # data是一个词典</code></pre>• 读入文本文件<br>• 可以指定注释、分隔符、编码等<pre><code>from io import StringIO
# 用字符串模拟一个file对象
c = StringIO("0 1\n2 3")
np.loadtxt(c)
array([[ 0., 1.],
[ 2., 3.]])</code></pre>• 读入图像文件<pre><code>from scipy.misc import imread
im = imread("lenna.png")
print(im.shape, im.dtype)
# (330, 330, 3) uint8
im_grey = im[:,:,0]*0.299 + im[:,:,1]*0.587 + im[:,:,2]*0.114
import matplotlib.pyplot as plt
plt.imshow(im_grey, cmap='gray')
plt.show()</code></pre></li>
<li>ufunc<br>• 除了四则运算，常见的数学函数也作为ufunc提供，可以在数组上操作.<br>• 单次numpy.sin的速度只有math.sin的1/4，但大数组的numpy.sin比math.sin快20多倍。这是因为numpy.sin在C语言级别进行循环计算。</li>
<li>聚集运算<br>• np.sum(a) 对数组a求和<br>• 其他参数：<br>—— axis=None 在特定的维度上求和，默认为全部<br>求和<br>—— out=None 输出直接存入该参数<br>—— initial=初始值<pre><code>np.sum([[0, 1], [0, 5]])
#6
np.sum([[0, 1], [0, 5]], axis=0)
#array([0, 6])
np.sum([[0, 1], [0, 5]], axis=1)
#array([1, 5])
np.sum([])
#0.0</code></pre></li>
<li>其他聚集操作<br>• all 布尔型：与<br>• any 布尔型：或<br>• max 最大值<br>• min 最小值<br>• mean 均值<br>• std 标准差</li>
<li>类型转换<br>.astype(T) 转为T类型<pre><code>x = array([[0, 1],
[2, 3]])
x.astype(np.float32)
"""
array([[0., 1.],
[2., 3.]], dtype=float32)
"""</code></pre></li>
<li>矩阵运算<br>• NumPy对于多维数组的运 算，缺省情况下并不使用矩阵运算（特指 乘除法）。<br>• numpy库提供了matrix类，使用matrix类创建矩阵对象，它们的加减乘除运算缺省采用矩阵方式计算<br>• NumPy中同时存在ndarray和matrix对象，容易混淆，需要注意。</li>
<li>矩阵运算<br>• 矩阵的乘积可以使用dot函数进行计算。<br>• dot<br>—— 对于两个一维的数组，计算的是这两个数组对<br>应下标元素的乘积和（内积）。<br>—— 对于二维数组，计算的是两个数组的矩阵乘积。<br>—— 对于多维数组，通用计算公式为数组a的最后一维上的所有元素与数组b的倒数第二维上的所有元素的乘积和：<br>• dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])<pre><code>a = np.array([[2, 0], [0, 1]])
b = np.array([[4, 1], [2, 2]])
c = np.dot(a, b)  
"""
array([[8, 2],
[2, 2]])
"""</code></pre></li>
<li>排序<br>• .sort() 对数组进行排序，将改变数组的内容。<br>• .argsort() 返冋数组的排序下标<pre><code>a = np.array([5,3,2,4,1])
a.argsort()
array([4, 2, 1, 3, 0], dtype=int64)</code></pre></li>
<li>NumPy模块<br>• numpy.linalg模块<br>—— 包含线性代数的函数。可以计算逆矩阵、求特征值、奇异值分解、解线性方程组以及求解行列式、秩等<br>• numpy.fft模块<br>—— 提供了快速傅里叶变换及其逆变换。<br>• numpy.random 模块<br>—— 支持二项分布、超几何分布、正态分布等</li>
<li>numpy.linalg<br>• 解方程<br>3 * x0 +  x1 = 9<br>x0 + 2 * x1 = 8<pre><code>a = np.array([[3,1], [1,2]])
b = np.array([9,8])
x = np.linalg.solve(a, b)
x
array([ 2., 3.])
np.allclose(np.dot(a, x), b)</code></pre><h5 id="MATPLOTLIB"><a href="#MATPLOTLIB" class="headerlink" title="MATPLOTLIB"></a>MATPLOTLIB</h5>• Python绘图库。<br>• 由 John Hunter (1968-2012) 创建。<br>• 拥有一套和Matlab几乎相同语法的绘图库。<br>• 也拥有另一套面向对象的绘图库。<br>• <a href="http://matplotlib.org/" target="_blank" rel="noopener">http://matplotlib.org/</a> 参考 Example 和 Gallery。</li>
<li>导入<br>• import matplotlib.pyplot as plt<br>• from matplotlib.pyplot import *<br>• pyplot模块模拟了matlab接口</li>
<li>入门示例<pre><code>import numpy as np
from matplotlib.pyplot import *
#or: from matplotlib.pylab import * 
# pylab = pyplot + numpy
x = np.linspace(0, 5, 10)
y = x ** 2
figure()
plot(x, y, 'r‐o')
xlabel('x')
ylabel('y')
title('title')
show()</code></pre></li>
<li>Plot<br>• x:如果缺少x则按照(0,1,2,3…)<br>• y<br>• “r‐o”: red, 实线, 圆点<br>—— 类似有 “g‐‐x”  绿色虚线X<br>• plot改为semilogx, semilogy, loglog<br>可以变为对数坐标尺度</li>
<li>颜色<br>• 单词，如’red’<br>• 字母，如’r’<br>• 6位16进制数，如’#FF0000’或’#ff0000’<br>• 三(RGB)或四(RGBA)元组，如(1, 0, 0)或(1,0,0,1)<br>• 灰度字符串，如’0.8’<pre><code>import numpy as np
import matplotlib.pyplot as plt
a = b = np.linspace(0, 3, 50)
c = np.exp(a)
d = c[::‐1]
plt.plot(a, c, 'r‐‐', label='Model length')
plt.plot(a, d, 'b:', label='Data length')
plt.plot(a, c+d, 'k', label='Total message length')
legend = plt.legend(loc='upper center', shadow=True)
legend.get_frame().set_facecolor('#00FFCC')
plt.show()</code></pre></li>
<li>保存绘图<br>• plt.savefig()<br>—— 文件名是必需参数。<br>—— 示例：plt.savefig(“abc.png”, bbox_inches=’tight’)<br>—— bboxinches=’tight’ 去掉不需要的白边。<br>• plt.show()<br>—— 只在屏幕上显示。</li>
<li>多个绘图<pre><code>x = np.linspace(0.0, 6.28, 100)
y1 = np.cos(x)
y2 = np.sin(x)
plt.subplot(2, 1, 1)
plt.plot(x, y1, 'yo‐')
plt.grid(True)
plt.subplot(2, 1, 2)
plt.plot(x, y2, 'r.‐')
plt.xlabel('time (s)')
plt.show()</code></pre></li>
<li>直方图<pre><code>mu, sigma = 100, 15
x = mu + sigma * np.random.randn(10000)
n, bins, patches = plt.hist(x, 50,
normed=1,
facecolor='g',
alpha=0.75)
plt.xlabel('Smarts')
plt.ylabel('Probability')
plt.title('Histogram of IQ')
plt.text(60, .025,
r'$\mu=100,\ \sigma=15$')
plt.axis([40, 160, 0, 0.03])
plt.grid(True)
plt.show()</code></pre></li>
<li>散点图<pre><code>x = np.random.random(50)
y = np.random.random(50)
c = np.random.random(50)  # color of points
s = 500 * np.random.random(50)  # size of points
fig, ax = plt.subplots()
im = ax.scatter(x, y, c=c, s=s, cmap=plt.cm.jet)
# Add a colorbar
fig.colorbar(im, ax=ax)
# set the color limits
im.set_clim(0.0, 1.0)</code></pre><h3 id="网络爬虫"><a href="#网络爬虫" class="headerlink" title="网络爬虫"></a>网络爬虫</h3><h5 id="检查网站地图"><a href="#检查网站地图" class="headerlink" title="检查网站地图"></a>检查网站地图</h5>• Sitemap（网站地图）<br>• 网站提供的Sitemap文件可以帮助爬虫定位网站所有网页的链接；<br>• Sitemap文件提供了爬取网站的有效方式，但该文件经常存在缺失、过期或不完整。<h5 id="检测网站构建技术"><a href="#检测网站构建技术" class="headerlink" title="检测网站构建技术"></a>检测网站构建技术</h5>• 构建网站的技术类型会对爬取产生影响。<br>—— 例如网页是动态生成的还是静态页面。<br>• 安装 builtwith 库，将URL作为参数，该库<br>返回网站使用的技术特征。<br>• pip install builtwith<h5 id="调研网站的所有者"><a href="#调研网站的所有者" class="headerlink" title="调研网站的所有者"></a>调研网站的所有者</h5>• 根据网站的所有者，判定爬虫的下载速度等；<br>• 为了找到网站的所有者，可以使用WHOIS协议查询域名的注册者。<br>• 安装：pip install python-whois<h5 id="下载单个网页"><a href="#下载单个网页" class="headerlink" title="下载单个网页"></a>下载单个网页</h5>• python提供了urllib2, requests等库<pre><code>import requests
url = 'http://www.weather.com.cn/weather/101010100.shtml' # URL地址
header = {
'User‐Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/53.0.2785.104 Safari/537.36
Core/1.53.3226.400 QQBrowser/9.6.11681.400'
}
req = requests.get(url, headers=header, timeout=60)
req.encoding = 'utf‐8' # 设置文本编码
code = req.status_code # 返回状态，200代表OK
print(code)</code></pre>• 遇到错误怎么办？(code!=200)<br>• 下载时遇到的错误经常是临时性的：<br>_ 如服务器过载时返回的503 Service Unavailable错误；<br>_ 对于此类错误，可以尝试重新下载。<br>• 非临时性错误<br>_ 如果服务器返回的是404 Not Found错误，说明该网页目前并不存在，再次尝试同样的请求也通常会再次出错。<br>• 400+错误发生在客户端，500+错误则发生在服务端。<br>• 在code为500+时可以重试下载，但通常应该等待一段时间。<h5 id="分析网页的三类技术"><a href="#分析网页的三类技术" class="headerlink" title="分析网页的三类技术"></a>分析网页的三类技术</h5>• 正则表达式<br>_ 无视HTML语言，直接利用正则表达式筛选出所需的部分，包括天气和URL；<br>• BeatifulSoup<br>_ 将HTML进行解析，利用树结构进行分析；<br>• lxml<br>_ 将HTML进行解析，基于XPATH查询语言进行分析。</li>
<li>BeatifulSoup<br>• Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库；<br>• 支持惯用的文档导航、查找、修改文档的方式；<br>• 提高效率，通常较正则表达式可以节省数小时甚至数天的工作时间。<br>• pip install beautifulsoup4<pre><code>from bs4 import BeautifulSoup
html_doc = """&lt;html&gt;&lt;head&gt;&lt;title&gt;The Dormouse's story&lt;/title&gt;&lt;/head&gt;
&lt;body&gt;
&lt;p class="title"&gt;&lt;b&gt;The Dormouse's story&lt;/b&gt;&lt;/p&gt;
&lt;p class="story"&gt;Once upon a time there were three little sisters;
and their names were
&lt;a href="http://example.com/elsie" class="sister"
id="link1"&gt;Elsie&lt;/a&gt;,
&lt;a href="http://example.com/lacie" class="sister"
id="link2"&gt;Lacie&lt;/a&gt; and
&lt;a href="http://example.com/tillie" class="sister"
id="link3"&gt;Tillie&lt;/a&gt;;
and they lived at the bottom of a well.&lt;/p&gt;
&lt;p class="story"&gt;...&lt;/p&gt;
"""
soup = BeautifulSoup(html_doc)
print(soup.prettify()) # 排版
soup.title
# &lt;title&gt;The Dormouse's story&lt;/title&gt;
soup.title.name
# 'title'
soup.title.string
# 'The Dormouse's story'
soup.title.parent.name
# 'head'
soup.p
# &lt;p class="title"&gt;&lt;b&gt;The Dormouse's story&lt;/b&gt;&lt;/p&gt;
soup.p['class']
# 'title'
soup.a
# &lt;a class="sister" href="http://example.com/elsie"
id="link1"&gt;Elsie&lt;/a&gt;
soup.find_all('a')
# [&lt;a class="sister" href="http://example.com/elsie"
id="link1"&gt;Elsie&lt;/a&gt;,
#  &lt;a class="sister" href="http://example.com/lacie"
id="link2"&gt;Lacie&lt;/a&gt;,
#  &lt;a class="sister" href="http://example.com/tillie"
id="link3"&gt;Tillie&lt;/a&gt;]
soup.find(id="link3")
# &lt;a class="sister" href="http://example.com/tillie"
id="link3"&gt;Tillie&lt;/a&gt;</code></pre>• 从文档中找到所有a标签的链接<pre><code>for link in soup.find_all('a'):
    print(link.get('href'))
# http://example.com/elsie
# http://example.com/lacie
# http://example.com/tillie</code></pre>• 从文档中获取所有文字内容<pre><code>print(soup.get_text())
# The Dormouse's story
#
# The Dormouse's story
#
# Once upon a time there were three little sisters; and their\names were
# Elsie, Lacie and ...</code></pre></li>
<li>如何遍历网页内容<br>• BS4提供了children, parents, next_element等<br>一系列方法，可以对元素的子元素、父元<br>素、兄弟元素等进行导航，从而遍历整个<br>网页。<br>• BS4也提供了正则表达式等方法。<br>• BS4的介绍可以参考：<br><a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html" target="_blank" rel="noopener">https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html</a></li>
<li>链接爬虫<br>• 链接爬虫表现得更像普通用户，它跟踪链接，访问感兴趣的内容。<br>• 通过跟踪所有链接的方式，可以下载整个网站的页面。<br>• 这种方法会下载大量并不需要的网页，通常应该利用正则表达式匹配/过滤需要爬取的网页。<br>• 避免链接爬虫陷阱<br>• 某些网站会动态生成页面内容，有可能造成理论上无限多的页面。<br>——例如：日历网站，链接指向“下个月”<br>• 通常应该定义爬虫最大深度，避免爬虫陷阱。<h3 id="图形界面开发GUI"><a href="#图形界面开发GUI" class="headerlink" title="图形界面开发GUI"></a>图形界面开发GUI</h3><a href="https://www.jianshu.com/p/db0af187ab26" target="_blank" rel="noopener">python图形化GUI：pyQt5详解</a><br><a href="https://www.jianshu.com/p/8ce24bd03978" target="_blank" rel="noopener">python图形化GUI：pyQt5-tools详解</a><h5 id="MVC"><a href="#MVC" class="headerlink" title="MVC"></a>MVC</h5>• Model（模型）是应用程序中用于处理应用程序数据逻辑的部<br>分，通常模型对象负责在数据库中存取数据。<br>• View（视图）是应用程序中处理数据显示的部分。通常视图是依据模型数据创建的。<br>• Controller（控制器）是应用程序中处理用户交互的部分。通常控制器负责从视图读取数据，控制用户输入，并向模型发送数据。<br>• MVC 分层有助于管理复杂的应用程序，因为您可以在一个时间内专门关注一个方面。例如，您可以在不依赖业务逻辑的情况下专注于视图设计。同时也让应用程序的测试更加容易。<br>• MVC 分层同时也简化了分组开发。不同的开发人员可同时开发视图、控制器逻辑和业务逻辑。</li>
</ul>
<p><a href="https://www.jianshu.com/p/38167906095e" target="_blank" rel="noopener">python：PIL图像处理</a></p>
<h3 id="自动化"><a href="#自动化" class="headerlink" title="自动化"></a>自动化</h3><h5 id="EXCEL自动化"><a href="#EXCEL自动化" class="headerlink" title="EXCEL自动化"></a>EXCEL自动化</h5><p>• Excel 是 Windows 环境下流行的、强大的电子表格应用。<br>—— 包括LibreOffice Calc，OpenOffice Calc，WPS等软件也可以读写xlsx格式。<br>• openpyxl 模块让 Python 程序能读取和修改Excel 电子表格文件。最新版本2.6.2。<br>• <a href="https://openpyxl.readthedocs.io" target="_blank" rel="noopener">https://openpyxl.readthedocs.io</a><br>• 安装：pip install openpyxl</p>
<ul>
<li>取得工作簿及工作表<pre><code>import openpyxl
wb = openpyxl.load_workbook('example.xlsx')
wb.sheetnames
sheet = wb['Sheet3']
sheet.title
anotherSheet = wb.active
anotherSheet</code></pre></li>
<li>取得单元格<pre><code>sheet = wb['Sheet1']
sheet['A1']
sheet['A1'].value
c = sheet['B1']
c.value
for i in range(1, 5):
  print(i, sheet.cell(row=i, column=2).value)</code></pre></li>
<li>取得矩形区域<pre><code>for rowOfCellObjects in sheet['A1':'C3']:
    for cellObj in rowOfCellObjects:
          print(cellObj.coordinate, cellObj.value)
    print('‐‐‐ END OF ROW ‐‐‐')</code></pre></li>
<li>取得行或者列：支持循环迭代<pre><code>for i in sheet.rows:
    print(i)
for i in sheet.columns:
    print(i)</code></pre></li>
<li>数据结果的保存<br>• 保存在txt文件中<br>• 保存在csv文件中<br>• 保存在py文件中<pre><code>import pprint
resultFile = open('result.py', 'w')
resultFile.write(
'pay_sum = ' + pprint.pformat(pay_sum)
)
resultFile.close()</code></pre></li>
<li>创建空白工作簿和表<pre><code>import openpyxl
wb = openpyxl.Workbook()
print(wb.sheetnames)
sh = wb.active
sh.title = "My Data"
wb.save("mydata.xlsx")</code></pre></li>
<li>创建和删除工作表<pre><code>import openpyxl
&gt;&gt;&gt; wb = openpyxl.Workbook()
&gt;&gt;&gt; wb.get_sheet_names()
['Sheet']
&gt;&gt;&gt; sh1 = wb.create_sheet()
&lt;Worksheet "Sheet1"&gt;
&gt;&gt;&gt; wb.get_sheet_names()
['Sheet', 'Sheet1']
&gt;&gt;&gt; wb.create_sheet(index=0, title='First Sheet')
&lt;Worksheet "First Sheet"&gt;
&gt;&gt;&gt; wb.get_sheet_names()
['First Sheet', 'Sheet', 'Sheet1']
&gt;&gt;&gt; wb.remove_sheet(sh1)   #删除表
&gt;&gt;&gt; wb.get_sheet_names()
['First Sheet', 'Sheet']</code></pre></li>
<li>将值写入单元格<pre><code>import openpyxl
wb = openpyxl.Workbook()
sheet = wb.active
sheet['A1'].value = 'Hello world!'
wb.save("hello.xlsx")</code></pre></li>
<li>其他功能<br>• 改变字体<br>• 使用公式<br>• 设置行高和列宽<br>• 单元格拆分<br>• 绘制图表<br>例子：乘法表<pre><code>import openpyxl
wb = openpyxl.Workbook()
sheet = wb.active
for i in range(1, 10):
sheet.cell(row=i+1, column=1).value = i
sheet.cell(row=1, column=i+1).value = i
for i in range(1, 10):
for j in range(1, 10):
sheet.cell(row=i+1, column=j+1).value=i*j
wb.save("99.xlsx")</code></pre><h5 id="WORD自动化"><a href="#WORD自动化" class="headerlink" title="WORD自动化"></a>WORD自动化</h5>• Microsoft公司的Word是一套功能丰富的办公软件，所提供的docx格式可以存储文本以及字体、颜色等丰富的信息。<br>• docx的读写比txt文件要复杂，需要第三方库的支持。<br>• pip install python‐docx<br>• 注意：导入的时候用 import docx</li>
<li>docx文件结构<br>• docx 文件有很多结构。<br>• 这些结构在 python-docx 中用 3 种不同的类型来表示。<br>• Document 对象表示整个文档。<br>• Document 对象包含一个 Paragraph 对象的列表，Paragraph即文档中的段落。<br>• 每个 Paragraph 对象都包含一个 Run 对象的列表。</li>
<li>读取文档<pre><code>import docx
doc = docx.Document('libai.docx')
print(len(doc.paragraphs)
# 8
print(doc.paragraphs[0].text)
# '铁杵成针'
print(doc.paragraphs[2].text)
# '李白是唐代的大诗人，但是小时候读书并不用功。...'
print(doc.paragraphs[2].runs)
#[&lt;docx.text.run.Run at 0x1e0e56a3c50&gt;,...]
print(doc.paragraphs[2].runs[0].text)
#'李白是唐代的大诗人，'
print(doc.paragraphs[2].runs[1].text)
#'但是小时候读书并不用功'</code></pre></li>
<li>获取Word中的纯文本<br>• 如果不关注样式，只希望获得所有的文本<br>• 参考代码实现：<pre><code>import docx
def getText(filename):
    doc = docx.Document(filename)
    fullText = []
    for para in doc.paragraphs:
          fullText.append(para.text)
    return '\n'.join(fullText)</code></pre></li>
<li>Word中的样式<br>• Word有很多样式，可以通过段落或run对象的style属性获得。<br>• 可以通过设置下列属性产生不同的样式<br><img src="/images/loading.gif" data-original="https://upload-images.jianshu.io/upload_images/14093662-cdf1dbbe2c7c7ddb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></li>
<li>修改样式<pre><code>import docx
doc = docx.Document('libai.docx')
doc.paragraphs[2].runs[0].underline = True
doc.save('restyled‐libai.docx')</code></pre></li>
<li>生成Word文档<br>• doc.add_paragraph(text) 新建一个段落，返回段落对象。<br>• para.add_run(text) 新建一个run，返回run对象。<br>• doc.add_heading(text, level) 新建一个标题，层级为level<br>• doc.add_picture(filename) 新建一个图片<pre><code>import docx
doc = docx.Document()
doc.add_heading('静夜思', 0)
doc.add_heading('李白', 1)
for s in ["床前明月光", "疑是地上霜", "举头望明月",
"低头思故乡"]:
para = doc.add_paragraph(s)
para.add_run("/")
doc.add_picture("green.jpg")
doc.save('mydoc.docx')</code></pre><h5 id="PDF自动化"><a href="#PDF自动化" class="headerlink" title="PDF自动化"></a>PDF自动化</h5>• PDF 表示 Portable Document Format 便携式文件格式，由Adobe Systems在1993年用于文件交换所发展出的文件格式。<br>• 本部分专注两件事：<br>—— 从 PDF 读取文本内容<br>—— 从已有的文档页面生成新的 PDF。<br>• pip install pyPDF2</li>
<li>PDF读取文字<pre><code>import PyPDF2
with open('04067093.pdf', 'rb') as pdfFile:
pdfReader = PyPDF2.PdfFileReader(pdfFile)
print("Total pages: ", pdfReader.numPages)
page0 = pdfReader.getPage(0)
print(page0.extractText())</code></pre></li>
<li>合并PDF<pre><code>import PyPDF2
pdf1File = open('00294849.pdf', 'rb')
pdf2File = open('04067093.pdf', 'rb')
pdf1Reader = PyPDF2.PdfFileReader(pdf1File)
pdf2Reader = PyPDF2.PdfFileReader(pdf2File)
pdfWriter = PyPDF2.PdfFileWriter()
for pageNum in range(pdf1Reader.numPages):
    pageObj = pdf1Reader.getPage(pageNum)
    pdfWriter.addPage(pageObj)
for pageNum in range(pdf2Reader.numPages):
    pageObj = pdf2Reader.getPage(pageNum)
    pdfWriter.addPage(pageObj)
pdfOutputFile = open('combined.pdf', 'wb')
pdfWriter.write(pdfOutputFile)
pdfOutputFile.close(); pdf1File.close(); pdf2File.close()</code></pre></li>
<li>页面旋转和叠加<br>• rotateClockwise(0, 90, 180, 270)<br>• rotateCounterClockwise(…)<br>_ 可以将页面对象旋转<br>• mergePage(anotherPage)<br>_ 可以将页面叠加（水印）<br>• 综合上述功能，可以实现pdf文件的合并、页面抽取、旋转、叠印等功能。</li>
<li>PDF中文编码问题<br>• pyPDF2不能读取中文编码的文字；<br>• 可以使用pdfminer库或其他类似的库。<pre><code>import io
from pdfminer.converter import TextConverter
from pdfminer.pdfinterp import PDFPageInterpreter
from pdfminer.pdfinterp import PDFResourceManager
from pdfminer.pdfpage import PDFPage
def extract_text_from_pdf(pdf_path):
  resource_manager = PDFResourceManager()
  fake_file_handle = io.StringIO()
  converter = TextConverter(resource_manager, fake_file_handle)
  page_interpreter = PDFPageInterpreter(resource_manager, converter)
  with open(pdf_path, 'rb') as fh:
      for page in PDFPage.get_pages(fh, caching=True):
          page_interpreter.process_page(page)
      text = fake_file_handle.getvalue()
  converter.close()
  fake_file_handle.close()
  if text:
      return text
if __name__ == '__main__':
print(extract_text_from_pdf('CH9‐图形界面开发A.pdf'))</code></pre><h5 id="图像处理自动化"><a href="#图像处理自动化" class="headerlink" title="图像处理自动化"></a>图像处理自动化</h5>• 图像处理已经是深入日常生活，Photoshop的缩写已经成为图像处理的代名词。<br>• 如果需要编辑大量的图像，手工编辑可能是漫长、枯燥的工作。<br>• Pillow 是一个第三方 Python 模块，用于处理图像文件。该模块包含一些函数，可以很容易地裁剪图像、调整图像大小，以及编辑图像的内容，从而轻松地自动编辑成千上万的图像。</li>
<li>颜色和 RGBA 值<br>• 计算机程序通常将图像中的颜色表示为RGBA 值。RGBA 值是一组数字，指定顔色中的红、绿、蓝和 alpha（透明度）的值。<br>• 这些值是从 0到 255（最高）的整数。<br>• 这些 RGBA 值分配给单个像素，像素是计算机屏幕上能显示一种颜色的最小点。<br>• 像素的 RGB 设置准确地告诉它应该显示哪种颜色的色彩。</li>
<li>Alpha通道<br>• 图像也有一个 alpha 值，用于生成 RGBA 值。如果图像显示在屏幕上，遮住了背景图像或桌面墙纸，alpha 值决定了“透过”颜色可以看到多少程度的背景。<br>• 如果alpha 值为 0，表示完全透明。<br>• 如果alpha 值为 255，表示完全不透明。</li>
<li>获取颜色<pre><code>&gt;&gt;&gt; from PIL import ImageColor
&gt;&gt;&gt; ImageColor.getcolor('red', 'RGBA')
(255, 0, 0, 255)
&gt;&gt;&gt; ImageColor.getcolor('RED', 'RGBA')
(255, 0, 0, 255)
&gt;&gt;&gt; ImageColor.getcolor('Black', 'RGBA')
(0, 0, 0, 255)
&gt;&gt;&gt; ImageColor.getcolor('chocolate', 'RGBA')
(210, 105, 30, 255)
&gt;&gt;&gt; ImageColor.getcolor('CornflowerBlue', 'RGBA')
(100, 149, 237, 255)</code></pre></li>
<li>图像坐标系<br>• 左上角坐标为(0,0)<br>• y正方向向下<br>• x正方向向右</li>
<li>Box<br>• 一个矩形元组参数，表示图像中的一个矩形区域。四个整数按顺序分别是：<br>_左：该矩形的最左边的 x 坐标。<br>_顶：该矩形的顶边的 y 坐标。<br>_右：该矩形的最右边右面一个像素的 x 坐标。<br>_底：该矩形的底边下面一个像素的 y 坐标。<br>• 矩形元组（3, 1, 9, 6）</li>
<li>图像的打开和存储<pre><code>&gt;&gt;&gt; from PIL import Image
&gt;&gt;&gt; img = Image.open('horse.jpg')
&gt;&gt;&gt; img.size
　 (1674, 1116)
&gt;&gt;&gt; width, height = img.size
&gt;&gt;&gt; img.format
'JPG'
&gt;&gt;&gt; img.save('horse.png')</code></pre></li>
<li>生成新图像<pre><code>from PIL import Image
im = Image.new('RGBA', (100, 200), 'purple')
im.save('purpleImage.png')
im2 = Image.new('RGBA', (20, 20))
im2.save('transparentImage.png')</code></pre></li>
<li>裁剪图片<pre><code>croppedIm = img.crop(
(600, 200, 1000, 800))
croppedIm.save('cropped‐horse.png')</code></pre></li>
<li>复制和粘贴<pre><code>from PIL import Image
img = Image.open('horse.jpg')
croppedIm = img.crop((600, 200, 1000, 800))
horsehead = croppedIm.copy()
img.paste(horsehead, (1200, 200))
img.save('horse2.jpg')</code></pre></li>
<li>调整图像大小及旋转图像<pre><code>from PIL import Image
img = Image.open('horse.jpg')
width, height = img.size
img44 = img.resize((width//4, height//4), Image.NEAREST)
img42 = img.resize((width//4, height//2), Image.NEAREST)
imgr30 = img.rotate(30)
img44.save('horse44.jpg')
img42.save('horse42.jpg')
imgr30.save('horse_r30.jpg')</code></pre></li>
<li>更改单个像素<br>• 单个像素的颜色通过 getpixel()和putpixel()方法取得和设置。它们都接受一个元组，表示像素的 x 和 y坐标。<br>• putpixel()方法还接受一个元组，作为该像素的颜色。这个顔色参数是四整数 RGBA 元组或三整数 RGB 元组。<br>• 注：1. 能改一个像素就能进行任意的图像编辑；</li>
</ul>
<ol start="2">
<li>图片像素很多时，本方法很慢。<pre><code>img = Image.new('RGB', (200, 100), 'black')
print(img.getpixel((0, 0)))
for x in range(100):
for y in range(50):
img.putpixel((x, y), (210, 210, 210))
img.save('putPixel.png')</code></pre></li>
</ol>
<ul>
<li>绘制形状<br>• ImageDraw 方法在图像上绘制各种形状。<br>• 点：point(xy, fill)方法绘制单个像素。xy 参数表示要画的点的列表。该列表可以是 x和 y 坐标的元组的列表，例如[(x, y), (x, y), …]，或是没有元组的 x和 y 坐标的列表，例如[x1, y1, x2, y2, …]。<br>• 线：line(xy, fill, width)方法绘制一条线或一系列的线。xy 是一个元组的列表，例如[(x, y), (x,y), …]，或整数列表，例如[x1, y1, x2, y2, …]。每个点都是正在绘制的线上的一个连接点。<br>• 矩形、椭圆、多边形、文字等。<pre><code>from PIL import Image, ImageDraw
im = Image.new('RGBA', (200, 200), 'white')
draw = ImageDraw.Draw(im)
draw.line([(0, 0), (199, 0), (199, 199), (0, 199), (0,
0)], fill='black')
draw.rectangle((20, 30, 60, 60), fill='blue')
draw.ellipse((120, 30, 160, 60), fill='red')
draw.polygon(((57, 87), (79, 62), (94, 85), (120, 90),
(103, 113)), fill='brown')
for i in range(100, 200, 10):
draw.line([(i, 0), (200, i ‐ 100)], fill='green')
im.save('drawing.png')</code></pre><h5 id="键盘鼠标自动化"><a href="#键盘鼠标自动化" class="headerlink" title="键盘鼠标自动化"></a>键盘鼠标自动化</h5>• 白盒：完成了解docx/xlsx格式细节，通过python直接生成符合格式的文档。<br>• 灰色：Word/Excel提供某种控制接口（如COM接口），通过COM接口操作Word/Excel软件达到预期目标。<br>• 黑色：缺乏控制接口，仅能通过模拟键盘和鼠标事件驱动GUI软件。</li>
<li>pyautogui<br>• pyautogui模块可以模拟鼠标移动、按键和滚动鼠标滚轮等。<br>• 本节仅介绍pyautogui的部分功能。<br>• <a href="http://pyautogui.readthedocs.org/" target="_blank" rel="noopener">http://pyautogui.readthedocs.org/</a><br>• 安装：<br>_ pip install PyGetWindow==0.0.1<br>_ pip install pyautogui</li>
<li>注意事项<br>• Python 能以想象不到的高速移动鼠标并击键。它可能太快，导致被控程序跟不上。<br>• 如果出了问题，而程序仍然继续到处移动鼠标，计算机就会失去控制（因为你的键盘和鼠标被人控制了）。<br>—— 如果程序自己在移动鼠标，停止它可能很难。你可能无法点击“关闭”按钮<br>• Windows 和 Linux  上，注销的热键是 Ctrl-Alt-Del ，有可能会失去目前没有保存的文档。</li>
<li>预防措施<br>• 设置脚本在每次函数调用后暂停一段时间，让用户有很短的时间窗口来控制鼠标和键盘。<br>—— 将pyautogui.PAUSE 变量设置为要暂停的秒数。如设置：pyautogui.PAUSE = 1.5。<br>• 开启pyautogui 自动防故障功能。<br>—— 将鼠标移到屏幕的左上角，将导致pyautogui.FailSafeException 异常。<br>—— 故障时应尽可能快地向左上移动鼠标，以触发异常。<br>—— 该异常可以用try语句捕获。</li>
<li>屏幕坐标系<br>• 左上角为原点<br>• x向右为正方向<br>• y向下为正方向<pre><code>import pyautogui as ag
width, height = ag.size()
print(width, height)
#1366, 768</code></pre></li>
<li>移动鼠标<pre><code>import pyautogui
for i in range(10):
ag.moveTo(100, 100, duration=0.25)
ag.moveTo(200, 100, duration=0.25)
ag.moveTo(200, 200, duration=0.25)
ag.moveTo(100, 200, duration=0.25)</code></pre></li>
<li>获取鼠标位置<br>• position()函数获得鼠标当前的位置。<br>• 为了持续跟踪获得鼠标位置，可以采用下述代码：<pre><code>print('Press Ctrl‐C to quit.')
try:
  while True:
      x, y = pyautogui.position()
      print(f"mouse at {x:4d}, {y:4d}")
except KeyboardInterrupt:
  print('\nDone.')</code></pre></li>
<li>点击鼠标<br>• 当前位置点击 click() 方法。<br>• 若在位置(x,y) 点击，采用click(x,y)方法。<br>• 默认情况下点击左键。若指定鼠标按键，则需要button关键字参数，取值为 ‘left’、’middle’或’right’。<br>• 例：<br>_ click(100, 150, button=’left’)<br>_ click(200, 250, button=’right’)<br>• 模拟鼠标按下：mouseDown()<br>• 释放鼠标按键：mouseUp()<br>• 函数参数与 click()<br>_ click = mouseDown + mouseUp<br>• 鼠标双击：doubleClick()</li>
<li>拖动鼠标<br>• Drag即按住一个按键不放同时移动鼠标。<br>_ 通过拖动文件图标，在文件夹之间移动文件；<br>_ 可以拖动绘图。<br>• dragTo() 和 dragRel() 函数将鼠标拖动到一个新的位置，或相对当前的位置。<br>_ 函数的参数与moveTo() 和 moveRel() 相似。<pre><code>import pyautogui as ag
import time
time.sleep(5)
ag.click()
distance = 200
while distance &gt; 0:
  ag.dragRel(distance, 0, duration=0.2) # move right
  distance = distance ‐ 5
  ag.dragRel(0, distance, duration=0.2) # move down
  ag.dragRel(‐distance, 0, duration=0.2) # move left
  distance = distance ‐ 5
  ag.dragRel(0, ‐distance, duration=0.2) # move up</code></pre></li>
<li>获取屏幕内容<pre><code>import pyautogui
im = pyautogui.screenshot()
im.save("capture.png")</code></pre>• 做GUI自动测试时，可以利用截图分析按钮是否正常或者变灰（利用Pillow库的getpixel方法）。<br>• 可以做一个软件，随着鼠标移动，自动取得不同位置的颜色。</li>
<li>屏幕图像识别<br>• 提前准备一幅（截图后取出）的局部图像：<br>• locateOnScreen(‘want.png’)<br>• 找到屏幕上完全匹配的图像所在的box，然后可在box的中心（或其他位置）进行点击。</li>
<li>键盘<br>• typewrite()方法模拟发送按键<br>_ typewrite(‘Hello world!’)<br>_ typewrite([‘a’, ‘b’, ‘left’, ‘left’,’X’, ‘Y’])<br>_ 前者均为正常按键<br>_ 后者的’left’表示“左方向键”</li>
<li>键盘：特殊键<br><img src="/images/loading.gif" data-original="https://upload-images.jianshu.io/upload_images/14093662-f6e85cea98792463.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></li>
<li>键盘模拟<br>• keyDown()和keyUp()将向计算发送虚拟的按键和释放。<br>• press() 函数模拟完整的击键。<pre><code>keyDown('shift');
press('1');
keyUp('shift')</code></pre>相当于 Shift-1 ，即“ ! ”键<br>• hotkey() 按参数自左向右依次模拟按键倒序模拟释放。<br>_ hotkey(‘ctrl’, ‘alt’, ‘shift’, ‘s’)</li>
<li>可能完成的任务<br>• 模拟键盘及鼠标，实现自动填表；<br>• 填写Excel表格；<br>• 编写Word文件。<br>• 自动玩游戏；<br>• 网络爬虫：<br>• 模拟键盘输入关键字，发送“回车”键，获得页面；<br>• 利用键盘另存当前页面；<br>• 点击“下一页”，继续另存当前页面<br>• 聊天机器人<br>• 模拟键盘输入微信、QQ等<br>• 在AI时代，视觉、听觉和模拟发声、模拟形象都可以实现。<h3 id="数据存储与程序调试"><a href="#数据存储与程序调试" class="headerlink" title="数据存储与程序调试"></a>数据存储与程序调试</h3><h5 id="数据转换存储"><a href="#数据转换存储" class="headerlink" title="数据转换存储"></a>数据转换存储</h5>• 数据的存储交换发生在：<br>_ 在同一程序的不同片段之间；<br>_ 在不同的程序之间；<br>_ 在不同主机之间。<br>• 这些数据可能存储一些简单的文本和数值，也可能是非常复杂具有结构的一组数据。<br>• 为了实现数据的存储和交换，有多种相对流行的数据存储交换方式：<br>_ 文件或数据库。</li>
<li>INI文件<br>• INI用来表示简单的、分层次的配置文件，其内涵类似于Python的词典。<br>• 本质是纯文本文件，但有一些简单的格式。</li>
<li>INI文件的读写<br>• 由于格式非常简单，可以基于一般文件的read/write进行存取。<br>• Python提供了内置库：<pre><code>import configparser
config = configparser.ConfigParser()
config.add_section('Init')
config.set('Init', 'Server', '127.0.0.1')
config.set('Init', 'Port', '12000')
with open('my.ini', 'wt') as configfile:
  config.write(configfile)</code></pre></li>
<li>pickle<br>• Pickle库可以实现任意python对象的存储。<pre><code>import pickle
todo = ['write a blog post',
'reply an email',
'read a book']
pickle_file = open('todo.pickle', 'wb')
pickle.dump(todo, pickle_file)</code></pre></li>
<li>Pickle &amp; cPickle<br>• Pickle<pre><code>pickle_file = open('todo.pickle', "rb")
todo = pickle.load(pickle_file)
pickle_file.close()
print(todo)</code></pre></li>
<li>JSON<br>• Pickle仅限于Python程序使用，如何和其他语言交互？<br>• JSON (JavaScript Object Notation) 是跨语言的轻量级数据交换格式。<br>• 易于被人工读取、修改，也容易被机器读取和写入。<br>• 符合 ECMA-262 3rd Edition标准。<br>• JSON语言无关，它可以方便的被 C, C++, C#,Java, JavaScript, Perl, Python等语言读取和生成。<br>• 结论：JSON是理想的数据交换格式，可以实<br>现跨语言的、跨计算机的复杂数据传输。<pre><code>import json
datastore = { "room‐number": 100,
"use": "reception",
"sq‐ft": 50,
"price": [100, 200, 300]
}
with open("ds.json", 'w') as f:
  json.dump(datastore, f)
with open("ds.json", 'r') as f:
  data = json.load(f)
print(data)</code></pre></li>
<li>数据库<br>• 文件存储不适用于大项目，此时需要使用数据库。<br>• 数据管理系统 Database Management System= DBMS<br>_ 一系列存储数据的文件；<br>_ 一系列程序用于访问和更新其中的数据。<br>• 目前最流行的数据库是关系型数据库。</li>
<li>SQLite<br>• SQlite 是开源的数据库，可以嵌入在其他程序中，不需要安装。<br>• 单机版本，不能并发、不能网络访问、不需要用户名密码鉴权（但可以加密）。<br>• Portable – 仅使用了ANSI-standard C语言，因此可在各种平台编译；<br>• Reliable – 良好的测试，开源代码；<br>• Small – 300 kb 的库，只需要16kb的stack和100kb的heap，甚至可以运行在单片机上。</li>
<li>建库<pre><code>import sqlite3
conn = sqlite3.connect('example.db')
c = conn.cursor()
c.execute('''CREATE TABLE money
(日期, 姓名, 支出)''')
for d, n, m in [("2019‐4‐1", "Li Lei", 52),
("2019‐4‐2", "Han Meimei", 300),
("2019‐4‐5", "Li Lei", 230),
("2019‐4‐8", "Li Lei", 170),
("2019‐4‐10", "Han Meimei", 96)]:
  c.execute("INSERT INTO money VALUES (?,?,?)",(d,n,m))
conn.commit()
conn.close()</code></pre></li>
<li>用库<pre><code>import sqlite3
conn = sqlite3.connect('example.db')
c = conn.cursor()
result = c.execute('''select 姓名, 支出
    from money where 支出&gt;100;''')
for row in result:
  name = row[0]
  pay = row[1]
  print(f"{name} pay {pay}&gt;100")
conn.close()</code></pre></li>
<li>其他格式<br>• MAT：Matlab数据存储格式<br>• Python可以直接读取MAT文件，Python也可以调用Matlab完成特定任务。<h5 id="目录处理"><a href="#目录处理" class="headerlink" title="目录处理"></a>目录处理</h5>• 查找目录下的子目录和文件<br>_ glob库<br>• 遍历目录<br>_ os.walk方法</li>
<li>实例<pre><code>import os
from os.path import join, getsize
for root, dirs, files in os.walk('.'):
print("root=", root)
print(sum(getsize(join(root, name)
) for name in files), end="")
print("bytes in", len(files),
"non‐directory files")</code></pre><h5 id="测试和调试"><a href="#测试和调试" class="headerlink" title="测试和调试"></a>测试和调试</h5></li>
<li>测试驱动Test-driven开发<br>• pytest是一个强大的Python测试工具。<br>• pytest是软件测试框架，它会自动找到用户写的测试用例，运行测试并报告结果。<br>• 支持插件或第三方扩展<br>• 容易与其他工具对接。<br>• pip install pytest</li>
<li>规则<br>• pytest 测试样例的规则：<br>_ 测试文件以 test_ 开头（以 <em>test 结尾也可以）<br>_ 测试类以 Test 开头，并且不能带有 <strong>init</strong> 方法<br>_ 测试函数以 test</em> 开头<br>_ 断言使用基本的 assert 即可<br>• pytest自动执行所有的测试，并报告通过和失败的测试用例数量。</li>
<li>print-调试</li>
<li>使用日志文件<br>• 对大规模程序长期运行而言，故障的机会是很少的，难以通过print获得；<br>• 日志是一种非常好的手段，可以用于记录程序运行过程中的各种信息。<br>• 理想的日志可以用来恢复和重现程序的运行过程。<br>• 内置的logging库。</li>
<li>日志等级<br><img src="/images/loading.gif" data-original="https://upload-images.jianshu.io/upload_images/14093662-1a0cf572c74b3490.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></li>
<li>利用IPython.embed调试<br>• from IPython import embed<br>• 在需要调试的位置加入embed()函数<br>• 可以在现场运行python解释器，可以自由执行任何python语句，包括：<br>_ 打印输出任何变量<br>_ 修改和删除任何变量<br>• print/logging应对复杂数据结构的能力不足，embed()是较为理想的选择。</li>
</ul>
<script>
        document.querySelectorAll('.github-emoji')
          .forEach(el => {
            if (!el.dataset.src) { return; }
            const img = document.createElement('img');
            img.style = 'display:none !important;';
            img.src = el.dataset.src;
            img.addEventListener('error', () => {
              img.remove();
              el.style.color = 'inherit';
              el.style.backgroundImage = 'none';
              el.style.background = 'none';
            });
            img.addEventListener('load', () => {
              img.remove();
            });
            document.body.appendChild(img);
          });
      </script>
            </div>
            <hr/>

            

    <div class="reprint" id="reprint-statement">
        
            <div class="reprint__author">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-user">
                        文章作者:
                    </i>
                </span>
                <span class="reprint-info">
                    <a href="https://jackhcc.github.io" rel="external nofollow noreferrer">JackHCC</a>
                </span>
            </div>
            <div class="reprint__type">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-link">
                        文章链接:
                    </i>
                </span>
                <span class="reprint-info">
                    <a href="https://jackhcc.github.io/posts/blog-python01.html">https://jackhcc.github.io/posts/blog-python01.html</a>
                </span>
            </div>
            <div class="reprint__notice">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-copyright">
                        版权声明:
                    </i>
                </span>
                <span class="reprint-info">
                    本博客所有文章除特別声明外，均采用
                    <a href="https://creativecommons.org/licenses/by/4.0/deed.zh" rel="external nofollow noreferrer" target="_blank">CC BY 4.0</a>
                    许可协议。转载请注明来源
                    <a href="https://jackhcc.github.io" target="_blank">JackHCC</a>
                    !
                </span>
            </div>
        
    </div>

    <script async defer>
      document.addEventListener("copy", function (e) {
        let toastHTML = '<span>复制成功，请遵循本文的转载规则</span><button class="btn-flat toast-action" onclick="navToReprintStatement()" style="font-size: smaller">查看</a>';
        M.toast({html: toastHTML})
      });

      function navToReprintStatement() {
        $("html, body").animate({scrollTop: $("#reprint-statement").offset().top - 80}, 800);
      }
    </script>



            <div class="tag_share" style="display: block;">
                <div class="post-meta__tag-list" style="display: inline-block;">
                    
                        <div class="article-tag">
                            
                                <a href="/tags/Python/">
                                    <span class="chip bg-color">Python</span>
                                </a>
                            
                        </div>
                    
                </div>
                <div class="post_share" style="zoom: 80%; width: fit-content; display: inline-block; float: right; margin: -0.15rem 0;">
                    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/libs/share/css/share.min.css">

<div id="article-share">
    
    
    <div class="social-share" data-sites="twitter,facebook,google,qq,qzone,wechat,weibo,douban,linkedin" data-wechat-qrcode-helper="<p>微信扫一扫即可分享！</p>"></div>
    <script src="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/libs/share/js/social-share.min.js"></script>
    

    

</div>

                </div>
            </div>
            
                <style>
    #reward {
        margin: 40px 0;
        text-align: center;
    }

    #reward .reward-link {
        font-size: 1.4rem;
        line-height: 38px;
    }

    #reward .btn-floating:hover {
        box-shadow: 0 6px 12px rgba(0, 0, 0, 0.2), 0 5px 15px rgba(0, 0, 0, 0.2);
    }

    #rewardModal {
        width: 320px;
        height: 350px;
    }

    #rewardModal .reward-title {
        margin: 15px auto;
        padding-bottom: 5px;
    }

    #rewardModal .modal-content {
        padding: 10px;
    }

    #rewardModal .close {
        position: absolute;
        right: 15px;
        top: 15px;
        color: rgba(0, 0, 0, 0.5);
        font-size: 1.3rem;
        line-height: 20px;
        cursor: pointer;
    }

    #rewardModal .close:hover {
        color: #ef5350;
        transform: scale(1.3);
        -moz-transform:scale(1.3);
        -webkit-transform:scale(1.3);
        -o-transform:scale(1.3);
    }

    #rewardModal .reward-tabs {
        margin: 0 auto;
        width: 210px;
    }

    .reward-tabs .tabs {
        height: 38px;
        margin: 10px auto;
        padding-left: 0;
    }

    .reward-content ul {
        padding-left: 0 !important;
    }

    .reward-tabs .tabs .tab {
        height: 38px;
        line-height: 38px;
    }

    .reward-tabs .tab a {
        color: #fff;
        background-color: #ccc;
    }

    .reward-tabs .tab a:hover {
        background-color: #ccc;
        color: #fff;
    }

    .reward-tabs .wechat-tab .active {
        color: #fff !important;
        background-color: #22AB38 !important;
    }

    .reward-tabs .alipay-tab .active {
        color: #fff !important;
        background-color: #019FE8 !important;
    }

    .reward-tabs .reward-img {
        width: 210px;
        height: 210px;
    }
</style>

<div id="reward">
    <a href="#rewardModal" class="reward-link modal-trigger btn-floating btn-medium waves-effect waves-light red">赏</a>

    <!-- Modal Structure -->
    <div id="rewardModal" class="modal">
        <div class="modal-content">
            <a class="close modal-close"><i class="fas fa-times"></i></a>
            <h4 class="reward-title">你的赏识是我前进的动力</h4>
            <div class="reward-content">
                <div class="reward-tabs">
                    <ul class="tabs row">
                        <li class="tab col s6 alipay-tab waves-effect waves-light"><a href="#alipay">支付宝</a></li>
                        <li class="tab col s6 wechat-tab waves-effect waves-light"><a href="#wechat">微 信</a></li>
                    </ul>
                    <div id="alipay">
                        <img src="/images/loading.gif" data-original="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/medias/reward/aliqr.png" class="reward-img" alt="支付宝打赏二维码">
                    </div>
                    <div id="wechat">
                        <img src="/images/loading.gif" data-original="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/medias/reward/wxqr.png" class="reward-img" alt="微信打赏二维码">
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<script>
    $(function () {
        $('.tabs').tabs();
    });
</script>
            
        </div>
    </div>

    
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/libs/gitalk/gitalk.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/css/my-gitalk.css">

<div class="card gitalk-card" data-aos="fade-up">
    <div class="comment_headling" style="font-size: 20px; font-weight: 700; position: relative; left: 20px; top: 15px; padding-bottom: 5px;">
        <i class="fas fa-comments fa-fw" aria-hidden="true"></i>
        <span>评论</span>
    </div>
    <div id="gitalk-container" class="card-content"></div>
</div>

<script src="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/libs/gitalk/gitalk.min.js"></script>
<script>
    let gitalk = new Gitalk({
        clientID: '3821a0bbb773038a51fc',
        clientSecret: '4b30b507d67ec5497ec0e77f43f80cb3e0d7dd3a',
        repo: 'JackHCC.github.io',
        owner: 'JackHCC',
        admin: "JackHCC",
        id: '2020-02-28T18-51-54',
        distractionFreeMode: false  // Facebook-like distraction free mode
    });

    gitalk.render('gitalk-container');
</script>
    

    

    

    

    

    

<article id="prenext-posts" class="prev-next articles">
    <div class="row article-row">
        
        <div class="article col s12 m6" data-aos="fade-up">
            <div class="article-badge left-badge text-color">
                <i class="fas fa-chevron-left"></i>&nbsp;上一篇</div>
            <div class="card">
                <a href="/posts/blog-python02.html">
                    <div class="card-image">
                        
                        
                        <img src="/images/loading.gif" data-original="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/medias/featureimages/6.jpg" class="responsive-img" alt="Python-Turtle详解">
                        
                        <span class="card-title">Python-Turtle详解</span>
                    </div>
                </a>
                <div class="card-content article-content">
                    <div class="summary block-with-text">
                        
                            Turtle海龟库详细介绍
                        
                    </div>
                    <div class="publish-info">
                        <span class="publish-date">
                            <i class="far fa-clock fa-fw icon-date"></i>2020-02-28
                        </span>
                        <span class="publish-author">
                            
                            <i class="fas fa-bookmark fa-fw icon-category"></i>
                            
                            <a href="/categories/Python/" class="post-category">
                                    Python
                                </a>
                            
                            
                        </span>
                    </div>
                </div>
                
                <div class="card-action article-tags">
                    
                    <a href="/tags/Python-Turtle/">
                        <span class="chip bg-color">Python | Turtle</span>
                    </a>
                    
                </div>
                
            </div>
        </div>
        
        
        <div class="article col s12 m6" data-aos="fade-up">
            <div class="article-badge right-badge text-color">
                下一篇&nbsp;<i class="fas fa-chevron-right"></i>
            </div>
            <div class="card">
                <a href="/posts/webshare1.html">
                    <div class="card-image">
                        
                        
                        <img src="/images/loading.gif" data-original="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/medias/featureimages/20.jpg" class="responsive-img" alt="一些实用有趣的Web分享">
                        
                        <span class="card-title">一些实用有趣的Web分享</span>
                    </div>
                </a>
                <div class="card-content article-content">
                    <div class="summary block-with-text">
                        
                            全球范围内检索有趣实用的网站【持续更新】
                        
                    </div>
                    <div class="publish-info">
                            <span class="publish-date">
                                <i class="far fa-clock fa-fw icon-date"></i>2020-02-27
                            </span>
                        <span class="publish-author">
                            
                            <i class="fas fa-bookmark fa-fw icon-category"></i>
                            
                            <a href="/categories/Share/" class="post-category">
                                    Share
                                </a>
                            
                            
                        </span>
                    </div>
                </div>
                
                <div class="card-action article-tags">
                    
                    <a href="/tags/Web/">
                        <span class="chip bg-color">Web</span>
                    </a>
                    
                </div>
                
            </div>
        </div>
        
    </div>
</article>

</div>



<!-- 代码块功能依赖 -->
<script type="text/javascript" src="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/libs/codeBlock/codeBlockFuction.js"></script>

<!-- 代码语言 -->

<script type="text/javascript" src="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/libs/codeBlock/codeLang.js"></script>


<!-- 代码块复制 -->

<script type="text/javascript" src="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/libs/codeBlock/codeCopy.js"></script>


<!-- 代码块收缩 -->

<script type="text/javascript" src="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/libs/codeBlock/codeShrink.js"></script>


<!-- 代码块折行 -->

<style type="text/css">
code[class*="language-"], pre[class*="language-"] { white-space: pre !important; }
</style>


    

</main>



    <footer class="page-footer bg-color">
    <div class="container row center-align" style="margin-bottom: 15px !important;">
        <div class="col s12 m8 l8 copy-right">
            Copyright&nbsp;&copy;
            <span id="year">2020</span>
            <a href="https://jackhcc.github.io" target="_blank">杰克成</a>
            |&nbsp;Powered by&nbsp;<a href="https://hexo.io/" target="_blank">Hexo</a>
            |&nbsp;Theme&nbsp;<a href="https://github.com/blinkfox/hexo-theme-matery" target="_blank">Matery</a>
            <br>
            
            &nbsp;<i class="fas fa-chart-area"></i>&nbsp;站点总字数:&nbsp;<span
                class="white-color">158.3k</span>&nbsp;字
            
            
            
            
            
            
            <span id="busuanzi_container_site_pv">
                |&nbsp;<i class="far fa-eye"></i>&nbsp;总访问量:&nbsp;<span id="busuanzi_value_site_pv"
                    class="white-color"></span>&nbsp;次
            </span>
            
            
            <span id="busuanzi_container_site_uv">
                |&nbsp;<i class="fas fa-users"></i>&nbsp;总访问人数:&nbsp;<span id="busuanzi_value_site_uv"
                    class="white-color"></span>&nbsp;人
            </span>
            
            <br>
            
            <span id="sitetime">载入运行时间...</span>
            <script>
                function siteTime() {
                    var seconds = 1000;
                    var minutes = seconds * 60;
                    var hours = minutes * 60;
                    var days = hours * 24;
                    var years = days * 365;
                    var today = new Date();
                    var startYear = "2020";
                    var startMonth = "2";
                    var startDate = "27";
                    var startHour = "6";
                    var startMinute = "30";
                    var startSecond = "0";
                    var todayYear = today.getFullYear();
                    var todayMonth = today.getMonth() + 1;
                    var todayDate = today.getDate();
                    var todayHour = today.getHours();
                    var todayMinute = today.getMinutes();
                    var todaySecond = today.getSeconds();
                    var t1 = Date.UTC(startYear, startMonth, startDate, startHour, startMinute, startSecond);
                    var t2 = Date.UTC(todayYear, todayMonth, todayDate, todayHour, todayMinute, todaySecond);
                    var diff = t2 - t1;
                    var diffYears = Math.floor(diff / years);
                    var diffDays = Math.floor((diff / days) - diffYears * 365);
                    var diffHours = Math.floor((diff - (diffYears * 365 + diffDays) * days) / hours);
                    var diffMinutes = Math.floor((diff - (diffYears * 365 + diffDays) * days - diffHours * hours) /
                        minutes);
                    var diffSeconds = Math.floor((diff - (diffYears * 365 + diffDays) * days - diffHours * hours -
                        diffMinutes * minutes) / seconds);
                    if (startYear == todayYear) {
                        document.getElementById("year").innerHTML = todayYear;
                        document.getElementById("sitetime").innerHTML = "本站已安全运行 " + diffDays + " 天 " + diffHours +
                            " 小时 " + diffMinutes + " 分钟 " + diffSeconds + " 秒";
                    } else {
                        document.getElementById("year").innerHTML = startYear + " - " + todayYear;
                        document.getElementById("sitetime").innerHTML = "本站已安全运行 " + diffYears + " 年 " + diffDays +
                            " 天 " + diffHours + " 小时 " + diffMinutes + " 分钟 " + diffSeconds + " 秒";
                    }
                }
                setInterval(siteTime, 1000);
            </script>
            
            <br>
            
        </div>
        <div class="col s12 m4 l4 social-link social-statis">
    <a href="https://github.com/JackHCC" class="tooltipped" target="_blank" data-tooltip="访问我的GitHub" data-position="top" data-delay="50">
        <i class="fab fa-github"></i>
    </a>



    <a href="mailto:jackcc0701@163.com" class="tooltipped" target="_blank" data-tooltip="邮件联系我" data-position="top" data-delay="50">
        <i class="fas fa-envelope-open"></i>
    </a>



    <a href="https://www.facebook.com/profile.php?id=100046343443643" class="tooltipped" target="_blank" data-tooltip="关注我的Facebook: https://www.facebook.com/profile.php?id=100046343443643" data-position="top" data-delay="50">
        <i class="fab fa-facebook-f"></i>
    </a>



    <a href="https://twitter.com/JackChe66021834" class="tooltipped" target="_blank" data-tooltip="关注我的Twitter: https://twitter.com/JackChe66021834" data-position="top" data-delay="50">
        <i class="fab fa-twitter"></i>
    </a>



    <a href="tencent://AddContact/?fromId=50&fromSubId=1&subcmd=all&uin=2508074836" class="tooltipped" target="_blank" data-tooltip="QQ联系我: 2508074836" data-position="top" data-delay="50">
        <i class="fab fa-qq"></i>
    </a>



    <a href="https://weibo.com/u/6885584679" class="tooltipped" target="_blank" data-tooltip="关注我的微博: https://weibo.com/u/6885584679" data-position="top" data-delay="50">
        <i class="fab fa-weibo"></i>
    </a>



    <a href="https://www.zhihu.com/people/8f8482f01f0d6a04e844efe32e0f0710" class="tooltipped" target="_blank" data-tooltip="关注我的知乎: https://www.zhihu.com/people/8f8482f01f0d6a04e844efe32e0f0710" data-position="top" data-delay="50">
        <i class="fab fa-zhihu1">知</i>
    </a>



</div>
    </div>
</footer>

<div class="progress-bar"></div>


    <!-- 搜索遮罩框 -->
<div id="searchModal" class="modal">
    <div class="modal-content">
        <div class="search-header">
            <span class="title"><i class="fas fa-search"></i>&nbsp;&nbsp;搜索</span>
            <input type="search" id="searchInput" name="s" placeholder="请输入搜索的关键字"
                   class="search-input">
        </div>
        <div id="searchResult"></div>
    </div>
</div>

<script src="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/js/search.js"></script>
<script type="text/javascript">
$(function () {
    searchFunc("https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/" + "search.xml", 'searchInput', 'searchResult');
});
</script>
    <!-- 回到顶部按钮 -->
<div id="backTop" class="top-scroll">
    <a class="btn-floating btn-large waves-effect waves-light" href="#!">
        <i class="fas fa-arrow-up"></i>
    </a>
</div>


    <script src="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/libs/materialize/materialize.min.js"></script>
    <script src="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/libs/masonry/masonry.pkgd.min.js"></script>
    <script src="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/libs/aos/aos.js"></script>
    <script src="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/libs/scrollprogress/scrollProgress.min.js"></script>
    <script src="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/libs/lightGallery/js/lightgallery-all.min.js"></script>
    <script src="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/js/matery.js"></script>

    <canvas class="fireworks" style="position: fixed;left: 0;top: 0;z-index: 1; pointer-events: none;" ></canvas>
    <script type="text/javascript" src="//cdn.bootcss.com/animejs/2.2.0/anime.min.js"></script>
    <script type="text/javascript" src="/js/fireworks.js"></script>

    <script type="text/javascript">
        //只在桌面版网页启用特效
        var windowWidth = $(window).width();
        if (windowWidth > 768) {
            document.write('<script type="text/javascript" src="/js/sakura.js"><\/script>'); }
    </script>

    <!-- weather -->
	<script type="text/javascript">
	WIDGET = {FID: 'TToslpmkVO'}
	</script>
	<script type="text/javascript" src="https://apip.weatherdt.com/float/static/js/r.js?v=1111"></script>


    <!-- Global site tag (gtag.js) - Google Analytics -->


    <!-- Baidu Analytics -->

<script>
    var _hmt = _hmt || [];
    (function () {
        var hm = document.createElement("script");
        hm.src = "https://hm.baidu.com/hm.js?";
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(hm, s);
    })();
</script>

    <!-- Baidu Push -->

    
    
    <script async src="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/libs/others/busuanzi.pure.mini.js"></script>
    

    
        <script src="//code.tidio.co/kqhlkxviiccyoa0czpfpu4ijuey9hfre.js"></script>
        <script> 
            $(document).ready(function () {
                setInterval(change_Tidio, 50);  
                function change_Tidio() { 
                    var tidio=$("#tidio-chat iframe");
                    if(tidio.css("display")=="block"&& $(window).width()>977 ){
                        document.getElementById("tidio-chat-iframe").style.bottom= ($("div#backTop.top-scroll").css("display")=="none" &&$(window).width()>977)>0? "-40px" : ($("div.toc-title").length&&$(window).width()>977)>0?"85px":"20px";   
                        document.getElementById("tidio-chat-iframe").style.right="-15px";   
                        document.getElementById("tidio-chat-iframe").style.height=parseInt(tidio.css("height"))>=520?"520px":tidio.css("height");
                        document.getElementById("tidio-chat-iframe").style.zIndex="997";
                    } 
                    else if(tidio.css("display")=="block"&&$(window).width()>601 &&$(window).width()<992 ){
                        document.getElementById("tidio-chat-iframe").style.bottom= ($("div#backTop.top-scroll").css("display")=="none" && 601< $(window).width()<992)>0? "-40px":"20px" ;   
                        document.getElementById("tidio-chat-iframe").style.right="-15px"; 
                        document.getElementById("tidio-chat-iframe").style.zIndex="997";
                    }
                    else if(tidio.css("display")=="block"&&$(window).width()<601 && parseInt(tidio.css("height"))<230){
                        document.getElementById("tidio-chat-iframe").style.bottom= ($("div#backTop.top-scroll").css("display")=="none" && $(window).width()<601)>0? "-10px":"45px" ;   
                        document.getElementById("tidio-chat-iframe").style.zIndex="997";
                    }
                    if( tidio.css("display")=="block"&&$(window).width()<601 && parseInt(tidio.css("height"))>=230){
                        document.getElementById("tidio-chat-iframe").style.zIndex="998";
                    }
                } 
            }); 
        </script>
    

    

    
    <script type="text/javascript" color="0,0,255"
        pointColor="0,0,255" opacity='0.7'
        zIndex="-1" count="99"
        src="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/libs/background/canvas-nest.js"></script>
    

    

    
    <script type="text/javascript" src="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/libs/background/ribbon-dynamic.js" async="async"></script>
    
    
    
    <script src="https://cdn.jsdelivr.net/gh/JackHCC/JackHCC.github.io/libs/instantpage/instantpage.js" type="module"></script>
    

        <script src="//cdn.jsdelivr.net/npm/js-base64/base64.min.js"></script>
        <script>
        $('a').each(function() {
          const $this = $(this);
          const href = $this.attr('href');
          if (href && href.match('^((http|https|thunder|qqdl|ed2k|Flashget|qbrowser|ftp|rtsp|mms)://)')) {
            const strs = href.split('/');
            if (strs.length >= 3) {
                const host = strs[2];
                if (host !== 'your_domain' || window.location.host) {
                    $this.attr('href', '/go.html?u='+Base64.encode(href)+'').attr('rel', 'external nofollow noopener noreferrer');
                    if (true) {
                        $this.attr('target', '_blank');
                    }
                }
            }
          }
        });
        </script><script>!function(e){var c=Array.prototype.slice.call(document.querySelectorAll("img[data-original]"));function i(){for(var r=0;r<c.length;r++)t=c[r],0<=(n=t.getBoundingClientRect()).bottom&&0<=n.left&&n.top<=(e.innerHeight||document.documentElement.clientHeight)&&function(){var t,n,e,i,o=c[r];t=o,n=function(){c=c.filter(function(t){return o!==t})},e=new Image,i=t.getAttribute("data-original"),e.onload=function(){t.src=i,n&&n()},e.src=i}();var t,n}i(),e.addEventListener("scroll",function(){var t,n;t=i,n=e,clearTimeout(t.tId),t.tId=setTimeout(function(){t.call(n)},500)})}(this);</script><script>window.addEventListener("load",function(){var t=/\.(gif|jpg|jpeg|tiff|png)$/i,r=/^data:image\/[a-z]+;base64,/;Array.prototype.slice.call(document.querySelectorAll("img[data-original]")).forEach(function(a){var e=a.parentNode;"A"===e.tagName&&(e.href.match(t)||e.href.match(r))&&(e.href=a.dataset.original)})});</script></body>

</html>

